541 prev next chunks index CyanogenMod/android_packages_apps_Trebuchet_c03f8c04714b919999dafa1551d6a2834ce6e15b_src/com/android/launcher3/Launcher.java {strict: [[b]], subset: [[b]]}
line based (standard git) jfstmerge spork
   1                                                                                                          
   2 /*                                                                                                       
   3  * Copyright (C) 2008 The Android Open Source Project                                                    
   4  *                                                                                                       
   5  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   6  * you may not use this file except in compliance with the License.                                      
   7  * You may obtain a copy of the License at                                                               
   8  *                                                                                                       
   9  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
  10  *                                                                                                       
  11  * Unless required by applicable law or agreed to in writing, software                                   
  12  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  14  * See the License for the specific language governing permissions and                                   
  15  * limitations under the License.                                                                        
  16  */                                                                                                      
  17                                                                                                          
  18 package com.android.launcher3;                                                                           
  19                                                                                                          
  20 import android.animation.Animator;                                                                       
  21 import android.animation.AnimatorListenerAdapter;                                                        
  22 import android.animation.AnimatorSet;                                                                    
  23 import android.animation.ObjectAnimator;                                                                 
  24 import android.animation.PropertyValuesHolder;                                                           
  25 import android.animation.TimeInterpolator;                                                               
  26 import android.animation.ValueAnimator;                                                                  
  27 import android.annotation.TargetApi;                                                                     
  28 import android.app.Activity;                                                                             
  29 import android.app.ActivityManager;                                                                      
  30 import android.app.ActivityOptions;                                                                      
  31 import android.app.AlertDialog;                                                                          
  32 import android.app.SearchManager;                                                                        
  33 import android.appwidget.AppWidgetHostView;                                                              
  34 import android.appwidget.AppWidgetManager;                                                               
  35 import android.appwidget.AppWidgetProviderInfo;                                                          
  36 import android.content.ActivityNotFoundException;                                                        
  37 import android.content.BroadcastReceiver;                                                                
  38 import android.content.ComponentCallbacks2;                                                              
  39 import android.content.ComponentName;                                                                    
  40 import android.content.ContentResolver;                                                                  
  41 import android.content.Context;                                                                          
  42 import android.content.DialogInterface;                                                                  
  43 import android.content.Intent;                                                                           
  44 import android.content.IntentFilter;                                                                     
  45 import android.content.SharedPreferences;                                                                
  46 import android.content.pm.ActivityInfo;                                                                  
  47 import android.content.pm.ApplicationInfo;                                                               
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.pm.PackageManager.NameNotFoundException;                                          
  50 import android.content.res.Configuration;                                                                
  51 import android.content.res.Resources;                                                                    
  52 import android.database.ContentObserver;                                                                 
  53 import android.graphics.Bitmap;                                                                          
  54 import android.graphics.Canvas;                                                                          
  55 import android.graphics.Color;                                                                           
  56 import android.graphics.Point;                                                                           
  57 import android.graphics.PorterDuff;                                                                      
  58 import android.graphics.Rect;                                                                            
  59 import android.graphics.drawable.Drawable;                                                               
  60 import android.net.Uri;                                                                                  
  61 import android.os.AsyncTask;                                                                             
  62 import android.os.Build;                                                                                 
  63 import android.os.Bundle;                                                                                
  64 import android.os.Environment;                                                                           
  65 import android.os.Handler;                                                                               
  66 import android.os.Message;                                                                               
  67 import android.os.StrictMode;                                                                            
  68 import android.os.SystemClock;                                                                           
  69 import android.speech.RecognizerIntent;                                                                  
  70 import android.text.Selection;                                                                           
  71 import android.text.SpannableStringBuilder;                                                              
  72 import android.text.TextUtils;                                                                           
  73 import android.text.method.TextKeyListener;                                                              
  74 import android.util.DisplayMetrics;                                                                      
  75 import android.util.Log;                                                                                 
  76 import android.view.Display;                                                                             
  77 import android.view.Gravity;                                                                             
  78 import android.view.HapticFeedbackConstants;                                                             
  79 import android.view.KeyEvent;                                                                            
  80 import android.view.LayoutInflater;                                                                      
  81 import android.view.Menu;                                                                                
  82 import android.view.MotionEvent;                                                                         
  83 import android.view.Surface;                                                                             
  84 import android.view.View;                                                                                
  85 import android.view.View.OnClickListener;                                                                
  86 import android.view.View.OnLongClickListener;                                                            
  87 import android.view.ViewAnimationUtils;                                                                  
  88 import android.view.ViewGroup;                                                                           
  89 import android.view.ViewTreeObserver;                                                                    
  90 import android.view.Window;                                                                              
  91 import android.view.WindowManager;                                                                       
  92 import android.view.accessibility.AccessibilityEvent;                                                    
  93 import android.view.animation.AccelerateInterpolator;                                                    
  94 import android.view.animation.DecelerateInterpolator;                                                    
  95 import android.view.inputmethod.InputMethodManager;                                                      
  96 import android.widget.Advanceable;                                                                       
  97 import android.widget.FrameLayout;                                                                       
  98 import android.widget.ImageView;                                                                         
  99 import android.widget.TextView;                                                                          
 100 import android.widget.Toast;                                                                             
 101                                                                                                          
 102 import com.android.launcher3.DropTarget.DragObject;                                                      
 103 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 104 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 105 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 106 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 107 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 108 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 109 import com.android.launcher3.compat.UserHandleCompat;                                                    
 110 import com.android.launcher3.compat.UserManagerCompat;                                                   
 111                                                                                                          
 112 import java.io.DataInputStream;                                                                          
 113 import java.io.DataOutputStream;                                                                         
 114 import java.io.File;                                                                                     
 115 import java.io.FileDescriptor;                                                                           
 116 import java.io.FileNotFoundException;                                                                    
 117 import java.io.FileOutputStream;                                                                         
 118 import java.io.IOException;                                                                              
 119 import java.io.PrintWriter;                                                                              
 120 import java.lang.reflect.Field;                                                                          
 121 import java.lang.reflect.InvocationTargetException;                                                      
 122 import java.lang.reflect.Method;                                                                         
 123 import java.text.DateFormat;                                                                             
 124 import java.util.ArrayList;                                                                              
 125 import java.util.Collection;                                                                             
 126 import java.util.Date;                                                                                   
 127 import java.util.HashMap;                                                                                
 128 import java.util.List;                                                                                   
 129 import java.util.concurrent.atomic.AtomicInteger;                                                        
 130                                                                                                          
 131 /**                                                                                                      
 132  * Default launcher application.                                                                         
 133  */                                                                                                      
 134 public class Launcher extends Activity                                                                   
 135         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 136                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {            
 137     static final String TAG = "Launcher";                                                                
 138     static final boolean LOGD = false;                                                                   
 139                                                                                                          
 140     static final boolean PROFILE_STARTUP = false;                                                        
 141     static final boolean DEBUG_WIDGETS = false;                                                          
 142     static final boolean DEBUG_STRICT_MODE = false;                                                      
 143     static final boolean DEBUG_RESUME_TIME = false;                                                      
 144     static final boolean DEBUG_DUMP_LOG = false;                                                         
 145                                                                                                          
 146     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 147                                                                                                          
 148     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 149     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 150     private static final int REQUEST_PICK_SHORTCUT = 7;                                                  
 151     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 152     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 153                                                                                                          
 154     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 155     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 156                                                                                                          
 157     /**                                                                                                  
 158      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 159      * request codes used internally.                                                                    
 160      */                                                                                                  
 161     protected static final int REQUEST_LAST = 100;                                                       
 162                                                                                                          
 163     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 164                                                                                                          
 165     static final int SCREEN_COUNT = 5;                                                                   
 166     static final int DEFAULT_SCREEN = 2;                                                                 
 167                                                                                                          
 168     // To turn on these properties, type                                                                 
 169     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 170     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                        
 171     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 172     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                
 173                                                                                                          
 174     // The Intent extra that defines whether to ignore the launch animation                              
 175     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 176             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 177                                                                                                          
 178     // Type: int                                                                                         
 179     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 180     // Type: int                                                                                         
 181     private static final String RUNTIME_STATE = "launcher.state";                                        
 182     // Type: int                                                                                         
 183     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 190     // Type: boolean                                                                                     
 191     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 192     // Type: long                                                                                        
 193     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 194     // Type: int                                                                                         
 195     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 196     // Type: int                                                                                         
 197     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 198     // Type: parcelable                                                                                  
 199     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 200     // Type: parcelable                                                                                  
 201     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 202     // Type: int[]                                                                                       
 203     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 204                                                                                                          
 205     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 206     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 207                                                                                                          
 208     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 209     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 210             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 211                                                                                                          
 212     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";        
 213     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                      
 214             "com.android.launcher.toolbar_search_icon";                                                  
 215     private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                
 216             "com.android.launcher.toolbar_voice_search_icon";                                            
 217                                                                                                          
 218     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 219     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 220                                                                                                          
 221     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 222                                                                                                          
 223     /** The different states that Launcher can be in. */                                                 
 224     private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                
 225     private State mState = State.WORKSPACE;                                                              
 226     private AnimatorSet mStateAnimation;                                                                 
 227                                                                                                          
 228     private boolean mIsSafeModeEnabled;                                                                  
 229                                                                                                          
 230     static final int APPWIDGET_HOST_ID = 1024;                                                           
 231     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 232     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 233     private static final int ACTIVITY_START_DELAY = 1000;                                                
 234                                                                                                          
 235     private static final Object sLock = new Object();                                                    
 236     private static int sScreen = DEFAULT_SCREEN;                                                         
 237                                                                                                          
 238     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 239     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 240                                                                                                          
 241     // How long to wait before the new-shortcut animation automatically pans the workspace               
 242     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 243     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 244     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 245     private static final int SINGLE_FRAME_DELAY = 16;                                                    
 246                                                                                                          
 247     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 248             = new CloseSystemDialogsIntentReceiver();                                                    
 249     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 250                                                                                                          
 251     private LayoutInflater mInflater;                                                                    
 252                                                                                                          
 253     private Workspace mWorkspace;                                                                        
 254     private View mLauncherView;                                                                          
 255     private View mPageIndicators;                                                                        
 256     private DragLayer mDragLayer;                                                                        
 257     private DragController mDragController;                                                              
 258     private View mWeightWatcher;                                                                         
 259                                                                                                          
 260     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 261     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 262                                                                                                          
 263     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 264     private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                 
 265     private int mPendingAddWidgetId = -1;                                                                
 266                                                                                                          
 267     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 268                                                                                                          
 269     private FolderInfo mFolderInfo;                                                                      
 270                                                                                                          
 271     private Hotseat mHotseat;                                                                            
 272     private ViewGroup mOverviewPanel;                                                                    
 273                                                                                                          
 274     private View mAllAppsButton;                                                                         
 275                                                                                                          
 276     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 277     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 278     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 279     private boolean mAutoAdvanceRunning = false;                                                         
 280     private View mQsb;                                                                                   
 281                                                                                                          
 282     private Bundle mSavedState;                                                                          
 283     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 284     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 285     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 286     private State mOnResumeState = State.NONE;                                                           
 287                                                                                                          
 288     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 289                                                                                                          
 290     private boolean mWorkspaceLoading = true;                                                            
 291                                                                                                          
 292     private boolean mPaused = true;                                                                      
 293     private boolean mRestoring;                                                                          
 294     private boolean mWaitingForResult;                                                                   
 295     private boolean mOnResumeNeedsLoad;                                                                  
 296                                                                                                          
 297     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 298     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 299                                                                                                          
 300     private Bundle mSavedInstanceState;                                                                  
 301                                                                                                          
 302     private LauncherModel mModel;                                                                        
 303     private IconCache mIconCache;                                                                        
 304     private boolean mUserPresent = true;                                                                 
 305     private boolean mVisible = false;                                                                    
 306     private boolean mHasFocus = false;                                                                   
 307     private boolean mAttached = false;                                                                   
 308                                                                                                          
 309     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 310                                                                                                          
 311     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 312                                                                                                          
 313     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 314                                                                                                          
 315     // Related to the auto-advancing of widgets                                                          
 316     private final int ADVANCE_MSG = 1;                                                                   
 317     private final int mAdvanceInterval = 20000;                                                          
 318     private final int mAdvanceStagger = 250;                                                             
 319     private long mAutoAdvanceSentTime;                                                                   
 320     private long mAutoAdvanceTimeLeft = -1;                                                              
 321     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                     
 322         new HashMap<View, AppWidgetProviderInfo>();                                                      
 323                                                                                                          
 324     // Determines how long to wait after a rotation before restoring the screen orientation to           
 325     // match the sensor state.                                                                           
 326     private final int mRestoreScreenOrientationDelay = 500;                                              
 327                                                                                                          
 328     // External icons saved in case of resource changes, orientation, etc.                               
 329     private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];           
 330     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];            
 331                                                                                                          
 332     private Drawable mWorkspaceBackgroundDrawable;                                                       
 333                                                                                                          
 334     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 335     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 336                                                                                                          
 337     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 338     static Date sDateStamp = new Date();                                                                 
 339     static DateFormat sDateFormat =                                                                      
 340             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 341     static long sRunStart = System.currentTimeMillis();                                                  
 342     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 343                                                                                                          
 344     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 345     // it from the context.                                                                              
 346     private SharedPreferences mSharedPrefs;                                                              
 347                                                                                                          
 348     private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                   
 349                                                                                                          
 350     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 351     // when we scroll to that page on resume.                                                            
 352     private ImageView mFolderIconImageView;                                                              
 353     private Bitmap mFolderIconBitmap;                                                                    
 354     private Canvas mFolderIconCanvas;                                                                    
 355     private Rect mRectForFolderAnimation = new Rect();                                                   
 356                                                                                                          
 357     private BubbleTextView mWaitingForResume;                                                            
 358                                                                                                          
 359     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 360         public void run() {                                                                              
 361             if (mWorkspace != null) {                                                                    
 362                 mWorkspace.buildPageHardwareLayers();                                                    
 363             }                                                                                            
 364         }                                                                                                
 365     };                                                                                                   
 366                                                                                                          
 367     private static PendingAddArguments sPendingAddItem;                                                  
 368                                                                                                          
 369     public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);      
 370                                                                                                          
 371     private static class PendingAddArguments {                                                           
 372         int requestCode;                                                                                 
 373         Intent intent;                                                                                   
 374         long container;                                                                                  
 375         long screenId;                                                                                   
 376         int cellX;                                                                                       
 377         int cellY;                                                                                       
 378         int appWidgetId;                                                                                 
 379     }                                                                                                    
 380                                                                                                          
 381     private Stats mStats;                                                                                
 382                                                                                                          
 383     FocusIndicatorView mFocusHandler;                                                                    
 384                                                                                                          
 385     static boolean isPropertyEnabled(String propertyName) {                                              
 386         return Log.isLoggable(propertyName, Log.VERBOSE);                                                
 387     }                                                                                                    
 388                                                                                                          
 389     @Override                                                                                            
 390     protected void onCreate(Bundle savedInstanceState) {                                                 
 391         if (DEBUG_STRICT_MODE) {                                                                         
 392             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 393                     .detectDiskReads()                                                                   
 394                     .detectDiskWrites()                                                                  
 395                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 396                     .penaltyLog()                                                                        
 397                     .build());                                                                           
 398             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 399                     .detectLeakedSqlLiteObjects()                                                        
 400                     .detectLeakedClosableObjects()                                                       
 401                     .penaltyLog()                                                                        
 402                     .penaltyDeath()                                                                      
 403                     .build());                                                                           
 404         }                                                                                                
 405                                                                                                          
 406         super.onCreate(savedInstanceState);                                                              
 407                                                                                                          
 408         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 409         LauncherAppState app = LauncherAppState.getInstance();                                           
 410         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 411         // Determine the dynamic grid properties                                                         
 412         Point smallestSize = new Point();                                                                
 413         Point largestSize = new Point();                                                                 
 414         Point realSize = new Point();                                                                    
 415         Display display = getWindowManager().getDefaultDisplay();                                        
 416         display.getCurrentSizeRange(smallestSize, largestSize);                                          
 417         display.getRealSize(realSize);                                                                   
 418         DisplayMetrics dm = new DisplayMetrics();                                                        
 419         display.getMetrics(dm);                                                                          
 420                                                                                                          
 421         // Lazy-initialize the dynamic grid                                                              
 422         DeviceProfile grid = app.initDynamicGrid(this,                                                   
 423                 Math.min(smallestSize.x, smallestSize.y),                                                
 424                 Math.min(largestSize.x, largestSize.y),                                                  
 425                 realSize.x, realSize.y,                                                                  
 426                 dm.widthPixels, dm.heightPixels);                                                        
 427                                                                                                          
 428         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 429         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 430                 Context.MODE_PRIVATE);                                                                   
 431         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 432         mModel = app.setLauncher(this);                                                                  
 433         mIconCache = app.getIconCache();                                                                 
 434         mIconCache.flushInvalidIcons(grid);                                                              
 435         mDragController = new DragController(this);                                                      
 436         mInflater = getLayoutInflater();                                                                 
 437                                                                                                          
 438         mStats = new Stats(this);                                                                        
 439                                                                                                          
 440         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 441                                                                                                          
 442         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 443         mAppWidgetHost.startListening();                                                                 
 444                                                                                                          
 445         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 446         // this also ensures that any synchronous binding below doesn't re-trigger another               
 447         // LauncherModel load.                                                                           
 448         mPaused = false;                                                                                 
 449                                                                                                          
 450         if (PROFILE_STARTUP) {                                                                           
 451             android.os.Debug.startMethodTracing(                                                         
 452                     Environment.getExternalStorageDirectory() + "/launcher");                            
 453         }                                                                                                
 454                                                                                                          
 455         checkForLocaleChange();                                                                          
 456         setContentView(R.layout.launcher);                                                               
 457                                                                                                          
 458         setupViews();                                                                                    
 459         grid.layout(this);                                                                               
 460                                                                                                          
 461         registerContentObservers();                                                                      
 462                                                                                                          
 463         lockAllApps();                                                                                   
 464                                                                                                          
 465         mSavedState = savedInstanceState;                                                                
 466         restoreState(mSavedState);                                                                       
 467                                                                                                          
 468         if (PROFILE_STARTUP) {                                                                           
 469             android.os.Debug.stopMethodTracing();                                                        
 470         }                                                                                                
 471                                                                                                          
 472         if (!mRestoring) {                                                                               
 473             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 474                 // If the user leaves launcher, then we should just load items asynchronously when       
 475                 // they return.                                                                          
 476                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 477             } else {                                                                                     
 478                 // We only load the page synchronously if the user rotates (or triggers a                
 479                 // configuration change) while launcher is in the foreground                             
 480                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 481             }                                                                                            
 482         }                                                                                                
 483                                                                                                          
 484         // For handling default keys                                                                     
 485         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 486         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 487                                                                                                          
 488         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 489         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 490                                                                                                          
 491         updateGlobalIcons();                                                                             
 492                                                                                                          
 493         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 494         unlockScreenOrientation(true);                                                                   
 495                                                                                                          
 496         if (shouldShowIntroScreen()) {                                                                   
 497             showIntroScreen();                                                                           
 498         } else {                                                                                         
 499             showFirstRunActivity();                                                                      
 500             showFirstRunClings();                                                                        
 501         }                                                                                                
 502     }                                                                                                    
 503                                                                                                          
 504     @Override                                                                                            
 505     public void onLauncherProviderChange() { }                                                           
 506                                                                                                          
 507     /** To be overriden by subclasses to hint to Launcher that we have custom content */                 
 508     protected boolean hasCustomContentToLeft() {                                                         
 509         return false;                                                                                    
 510     }                                                                                                    
 511                                                                                                          
 512     /**                                                                                                  
 513      * To be overridden by subclasses to populate the custom content container and call                  
 514      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 515      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 516      */                                                                                                  
 517     protected void populateCustomContentContainer() {                                                    
 518     }                                                                                                    
 519                                                                                                          
 520     /**                                                                                                  
 521      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 522      * ensure the custom content page is added or removed if necessary.                                  
 523      */                                                                                                  
 524     protected void invalidateHasCustomContentToLeft() {                                                  
 525         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 526             // Not bound yet, wait for bindScreens to be called.                                         
 527             return;                                                                                      
 528         }                                                                                                
 529                                                                                                          
 530         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 531             // Create the custom content page and call the subclass to populate it.                      
 532             mWorkspace.createCustomContentContainer();                                                   
 533             populateCustomContentContainer();                                                            
 534         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 535             mWorkspace.removeCustomContentPage();                                                        
 536         }                                                                                                
 537     }                                                                                                    
 538                                                                                                          
 539     private void updateGlobalIcons() {                                                                   
 540         boolean searchVisible = false;                                                                   
 541         boolean voiceVisible = false;                                                                    
 542         // If we have a saved version of these external icons, we load them up immediately               
 543         int coi = getCurrentOrientationIndexForGlobalIcons();                                            
 544         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                           
 545             searchVisible = updateGlobalSearchIcon();                                                    
 546             voiceVisible = updateVoiceSearchIcon(searchVisible);                                         
 547         }                                                                                                
 548         if (sGlobalSearchIcon[coi] != null) {                                                            
 549              updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                             
 550              searchVisible = true;                                                                       
 551         }                                                                                                
 552         if (sVoiceSearchIcon[coi] != null) {                                                             
 553             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                
 554             voiceVisible = true;                                                                         
 555         }                                                                                                
 556         if (mSearchDropTargetBar != null) {                                                              
 557             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
 558         }                                                                                                
 559     }                                                                                                    
 560                                                                                                          
 561     private void checkForLocaleChange() {                                                                
 562         if (sLocaleConfiguration == null) {                                                              
 563             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 564                 @Override                                                                                
 565                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 566                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 567                     readConfiguration(Launcher.this, localeConfiguration);                               
 568                     return localeConfiguration;                                                          
 569                 }                                                                                        
 570                                                                                                          
 571                 @Override                                                                                
 572                 protected void onPostExecute(LocaleConfiguration result) {                               
 573                     sLocaleConfiguration = result;                                                       
 574                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 575                 }                                                                                        
 576             }.execute();                                                                                 
 577             return;                                                                                      
 578         }                                                                                                
 579                                                                                                          
 580         final Configuration configuration = getResources().getConfiguration();                           
 581                                                                                                          
 582         final String previousLocale = sLocaleConfiguration.locale;                                       
 583         final String locale = configuration.locale.toString();                                           
 584                                                                                                          
 585         final int previousMcc = sLocaleConfiguration.mcc;                                                
 586         final int mcc = configuration.mcc;                                                               
 587                                                                                                          
 588         final int previousMnc = sLocaleConfiguration.mnc;                                                
 589         final int mnc = configuration.mnc;                                                               
 590                                                                                                          
 591         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 592                                                                                                          
 593         if (localeChanged) {                                                                             
 594             sLocaleConfiguration.locale = locale;                                                        
 595             sLocaleConfiguration.mcc = mcc;                                                              
 596             sLocaleConfiguration.mnc = mnc;                                                              
 597                                                                                                          
 598             mIconCache.flush();                                                                          
 599                                                                                                          
 600             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 601             new AsyncTask<Void, Void, Void>() {                                                          
 602                 public Void doInBackground(Void ... args) {                                              
 603                     writeConfiguration(Launcher.this, localeConfiguration);                              
 604                     return null;                                                                         
 605                 }                                                                                        
 606             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 607         }                                                                                                
 608     }                                                                                                    
 609                                                                                                          
 610     private static class LocaleConfiguration {                                                           
 611         public String locale;                                                                            
 612         public int mcc = -1;                                                                             
 613         public int mnc = -1;                                                                             
 614     }                                                                                                    
 615                                                                                                          
 616     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 617         DataInputStream in = null;                                                                       
 618         try {                                                                                            
 619             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFS));               
 620             configuration.locale = in.readUTF();                                                         
 621             configuration.mcc = in.readInt();                                                            
 622             configuration.mnc = in.readInt();                                                            
 623         } catch (FileNotFoundException e) {                                                              
 624             // Ignore                                                                                    
 625         } catch (IOException e) {                                                                        
 626             // Ignore                                                                                    
 627         } finally {                                                                                      
 628             if (in != null) {                                                                            
 629                 try {                                                                                    
 630                     in.close();                                                                          
 631                 } catch (IOException e) {                                                                
 632                     // Ignore                                                                            
 633                 }                                                                                        
 634             }                                                                                            
 635         }                                                                                                
 636     }                                                                                                    
 637                                                                                                          
 638     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 639         DataOutputStream out = null;                                                                     
 640         try {                                                                                            
 641             out = new DataOutputStream(context.openFileOutput(                                           
 642                     LauncherFiles.LAUNCHER_PREFS, MODE_PRIVATE));                                        
 643             out.writeUTF(configuration.locale);                                                          
 644             out.writeInt(configuration.mcc);                                                             
 645             out.writeInt(configuration.mnc);                                                             
 646             out.flush();                                                                                 
 647         } catch (FileNotFoundException e) {                                                              
 648             // Ignore                                                                                    
 649         } catch (IOException e) {                                                                        
 650             //noinspection ResultOfMethodCallIgnored                                                     
 651             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFS).delete();                            
 652         } finally {                                                                                      
 653             if (out != null) {                                                                           
 654                 try {                                                                                    
 655                     out.close();                                                                         
 656                 } catch (IOException e) {                                                                
 657                     // Ignore                                                                            
 658                 }                                                                                        
 659             }                                                                                            
 660         }                                                                                                
 661     }                                                                                                    
 662                                                                                                          
 663     public Stats getStats() {                                                                            
 664         return mStats;                                                                                   
 665     }                                                                                                    
 666                                                                                                          
 667     public LayoutInflater getInflater() {                                                                
 668         return mInflater;                                                                                
 669     }                                                                                                    
 670                                                                                                          
 671     boolean isDraggingEnabled() {                                                                        
 672         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 673         // that is subsequently removed from the workspace in startBinding().                            
 674         return !mModel.isLoadingWorkspace();                                                             
 675     }                                                                                                    
 676                                                                                                          
 677     static int getScreen() {                                                                             
 678         synchronized (sLock) {                                                                           
 679             return sScreen;                                                                              
 680         }                                                                                                
 681     }                                                                                                    
 682                                                                                                          
 683     static void setScreen(int screen) {                                                                  
 684         synchronized (sLock) {                                                                           
 685             sScreen = screen;                                                                            
 686         }                                                                                                
 687     }                                                                                                    
 688                                                                                                          
 689     public static int generateViewId() {                                                                 
 690         if (Build.VERSION.SDK_INT >= 17) {                                                               
 691             return View.generateViewId();                                                                
 692         } else {                                                                                         
 693             // View.generateViewId() is not available. The following fallback logic is a copy            
 694             // of its implementation.                                                                    
 695             for (;;) {                                                                                   
 696                 final int result = sNextGeneratedId.get();                                               
 697                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 698                 int newValue = result + 1;                                                               
 699                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 700                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 701                     return result;                                                                       
 702                 }                                                                                        
 703             }                                                                                            
 704         }                                                                                                
 705     }                                                                                                    
 706                                                                                                          
 707     public int getViewIdForItem(ItemInfo info) {                                                         
 708         // This cast is safe given the > 2B range for int.                                               
 709         int itemId = (int) info.id;                                                                      
 710         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 711             return mItemIdToViewId.get(itemId);                                                          
 712         }                                                                                                
 713         int viewId = generateViewId();                                                                   
 714         mItemIdToViewId.put(itemId, viewId);                                                             
 715         return viewId;                                                                                   
 716     }                                                                                                    
 717                                                                                                          
 718     /**                                                                                                  
 719      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 720      * a configuration step, this allows the proper animations to run after other transitions.           
 721      */                                                                                                  
 722     private long completeAdd(PendingAddArguments args) {                                                 
 723         long screenId = args.screenId;                                                                   
 724         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 725             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 726             // that the drop page actually exists.                                                       
 727             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 728         }                                                                                                
 729                                                                                                          
 730         switch (args.requestCode) {                                                                      
 731             case REQUEST_CREATE_SHORTCUT:                                                                
 732                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 733                         args.cellY);                                                                     
 734                 break;                                                                                   
 735             case REQUEST_CREATE_APPWIDGET:                                                               
 736                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 737                 break;                                                                                   
 738             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 739                 completeRestoreAppWidget(args.appWidgetId);                                              
 740                 break;                                                                                   
 741         }                                                                                                
 742         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 743         // if you turned the screen off and then back while in All Apps, Launcher would not              
 744         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 745         resetAddInfo();                                                                                  
 746         return screenId;                                                                                 
 747     }                                                                                                    
 748                                                                                                          
 749     @Override                                                                                            
 750     protected void onActivityResult(                                                                     
 751             final int requestCode, final int resultCode, final Intent data) {                            
 752         // Reset the startActivity waiting flag                                                          
 753         setWaitingForResult(false);                                                                      
 754         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 755         mPendingAddWidgetId = -1;                                                                        
 756                                                                                                          
 757         Runnable exitSpringLoaded = new Runnable() {                                                     
 758             @Override                                                                                    
 759             public void run() {                                                                          
 760                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 761                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 762             }                                                                                            
 763         };                                                                                               
 764                                                                                                          
 765         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 766             final int appWidgetId = data != null ?                                                       
 767                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 768             if (resultCode == RESULT_CANCELED) {                                                         
 769                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 770                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 771                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 772             } else if (resultCode == RESULT_OK) {                                                        
 773                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 774                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 775             }                                                                                            
 776             return;                                                                                      
 777         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 778             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 779                 mWorkspace.exitOverviewMode(false);                                                      
 780             }                                                                                            
 781             return;                                                                                      
 782         }                                                                                                
 783                                                                                                          
 784         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 785                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 786                                                                                                          
 787         final boolean workspaceLocked = isWorkspaceLocked();                                             
 788         // We have special handling for widgets                                                          
 789         if (isWidgetDrop) {                                                                              
 790             final int appWidgetId;                                                                       
 791             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 792                     : -1;                                                                                
 793             if (widgetId < 0) {                                                                          
 794                 appWidgetId = pendingAddWidgetId;                                                        
 795             } else {                                                                                     
 796                 appWidgetId = widgetId;                                                                  
 797             }                                                                                            
 798                                                                                                          
 799             final int result;                                                                            
 800             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 801                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 802                         "returned from the widget configuration activity.");                             
 803                 result = RESULT_CANCELED;                                                                
 804                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 805                 final Runnable onComplete = new Runnable() {                                             
 806                     @Override                                                                            
 807                     public void run() {                                                                  
 808                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 809                     }                                                                                    
 810                 };                                                                                       
 811                 if (workspaceLocked) {                                                                   
 812                     // No need to remove the empty screen if we're mid-binding, as the                   
 813                     // the bind will not add the empty screen.                                           
 814                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 815                 } else {                                                                                 
 816                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 817                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 818                 }                                                                                        
 819             } else {                                                                                     
 820                 if (!workspaceLocked) {                                                                  
 821                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 822                         // When the screen id represents an actual screen (as opposed to a rank)         
 823                         // we make sure that the drop page actually exists.                              
 824                         mPendingAddInfo.screenId =                                                       
 825                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 826                     }                                                                                    
 827                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 828                                                                                                          
 829                     dropLayout.setDropPending(true);                                                     
 830                     final Runnable onComplete = new Runnable() {                                         
 831                         @Override                                                                        
 832                         public void run() {                                                              
 833                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 834                             dropLayout.setDropPending(false);                                            
 835                         }                                                                                
 836                     };                                                                                   
 837                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 838                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 839                 } else {                                                                                 
 840                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 841                             mPendingAddInfo);                                                            
 842                     sPendingAddItem = args;                                                              
 843                 }                                                                                        
 844             }                                                                                            
 845             return;                                                                                      
 846         }                                                                                                
 847                                                                                                          
 848         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 849             if (resultCode == RESULT_OK) {                                                               
 850                 // Update the widget view.                                                               
 851                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 852                         pendingAddWidgetId, mPendingAddInfo);                                            
 853                 if (workspaceLocked) {                                                                   
 854                     sPendingAddItem = args;                                                              
 855                 } else {                                                                                 
 856                     completeAdd(args);                                                                   
 857                 }                                                                                        
 858             }                                                                                            
 859             // Leave the widget in the pending state if the user canceled the configure.                 
 860             return;                                                                                      
 861         }                                                                                                
 862                                                                                                          
 863         // The pattern used here is that a user PICKs a specific application,                            
 864         // which, depending on the target, might need to CREATE the actual target.                       
 865                                                                                                          
 866         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 867         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 868         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 869             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 870                     mPendingAddInfo);                                                                    
 871             if (isWorkspaceLocked()) {                                                                   
 872                 sPendingAddItem = args;                                                                  
 873             } else {                                                                                     
 874                 completeAdd(args);                                                                       
 875                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 876                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 877             }                                                                                            
 878         } else if (resultCode == RESULT_CANCELED) {                                                      
 879             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 880                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 881         }                                                                                                
 882         mDragLayer.clearAnimatedView();                                                                  
 883     }                                                                                                    
 884                                                                                                          
 885     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 886             appWidgetId, ItemInfo info) {                                                                
 887         PendingAddArguments args = new PendingAddArguments();                                            
 888         args.requestCode = requestCode;                                                                  
 889         args.intent = data;                                                                              
 890         args.container = info.container;                                                                 
 891         args.screenId = info.screenId;                                                                   
 892         args.cellX = info.cellX;                                                                         
 893         args.cellY = info.cellY;                                                                         
 894         args.appWidgetId = appWidgetId;                                                                  
 895         return args;                                                                                     
 896     }                                                                                                    
 897                                                                                                          
 898     /**                                                                                                  
 899      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 900      *                                                                                                   
 901      * @param screenId the screen id to check                                                            
 902      * @return the new screen, or screenId if it exists                                                  
 903      */                                                                                                  
 904     private long ensurePendingDropLayoutExists(long screenId) {                                          
 905         CellLayout dropLayout =                                                                          
 906                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 907         if (dropLayout == null) {                                                                        
 908             // it's possible that the add screen was removed because it was                              
 909             // empty and a re-bind occurred                                                              
 910             mWorkspace.addExtraEmptyScreen();                                                            
 911             return mWorkspace.commitExtraEmptyScreen();                                                  
 912         } else {                                                                                         
 913             return screenId;                                                                             
 914         }                                                                                                
 915     }                                                                                                    
 916                                                                                                          
 917     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 918         CellLayout cellLayout =                                                                          
 919                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 920         Runnable onCompleteRunnable = null;                                                              
 921         int animationType = 0;                                                                           
 922                                                                                                          
 923         AppWidgetHostView boundWidget = null;                                                            
 924         if (resultCode == RESULT_OK) {                                                                   
 925             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 926             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 927                     mPendingAddWidgetInfo);                                                              
 928             boundWidget = layout;                                                                        
 929             onCompleteRunnable = new Runnable() {                                                        
 930                 @Override                                                                                
 931                 public void run() {                                                                      
 932                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 933                             mPendingAddInfo.screenId, layout, null);                                     
 934                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 935                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 936                 }                                                                                        
 937             };                                                                                           
 938         } else if (resultCode == RESULT_CANCELED) {                                                      
 939             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 940             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 941         }                                                                                                
 942         if (mDragLayer.getAnimatedView() != null) {                                                      
 943             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 944                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 945                     animationType, boundWidget, true);                                                   
 946         } else if (onCompleteRunnable != null) {                                                         
 947             // The animated view may be null in the case of a rotation during widget configuration       
 948             onCompleteRunnable.run();                                                                    
 949         }                                                                                                
 950     }                                                                                                    
 951                                                                                                          
 952     @Override                                                                                            
 953     protected void onStop() {                                                                            
 954         super.onStop();                                                                                  
 955         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 956     }                                                                                                    
 957                                                                                                          
 958     @Override                                                                                            
 959     protected void onStart() {                                                                           
 960         super.onStart();                                                                                 
 961         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 962     }                                                                                                    
 963                                                                                                          
 964     @Override                                                                                            
 965     protected void onResume() {                                                                          
 966         long startTime = 0;                                                                              
 967         if (DEBUG_RESUME_TIME) {                                                                         
 968             startTime = System.currentTimeMillis();                                                      
 969             Log.v(TAG, "Launcher.onResume()");                                                           
 970         }                                                                                                
 971         super.onResume();                                                                                
 972                                                                                                          
 973         // Restore the previous launcher state                                                           
 974         if (mOnResumeState == State.WORKSPACE) {                                                         
 975             showWorkspace(false);                                                                        
 976         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                             
 977             showAllApps(false, mAppsCustomizeContent.getContentType(), false);                           
 978         }                                                                                                
 979         mOnResumeState = State.NONE;                                                                     
 980                                                                                                          
 981         // Background was set to gradient in onPause(), restore to black if in all apps.                 
 982         setWorkspaceBackground(mState == State.WORKSPACE);                                               
 983                                                                                                          
 984         mPaused = false;                                                                                 
 985         if (mRestoring || mOnResumeNeedsLoad) {                                                          
 986             setWorkspaceLoading(true);                                                                   
 987             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
 988             mRestoring = false;                                                                          
 989             mOnResumeNeedsLoad = false;                                                                  
 990         }                                                                                                
 991         if (mBindOnResumeCallbacks.size() > 0) {                                                         
 992             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
 993             // execute them here                                                                         
 994             long startTimeCallbacks = 0;                                                                 
 995             if (DEBUG_RESUME_TIME) {                                                                     
 996                 startTimeCallbacks = System.currentTimeMillis();                                         
 997             }                                                                                            
 998                                                                                                          
 999             if (mAppsCustomizeContent != null) {                                                         
1000                 mAppsCustomizeContent.setBulkBind(true);                                                 
1001             }                                                                                            
1002             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1003                 mBindOnResumeCallbacks.get(i).run();                                                     
1004             }                                                                                            
1005             if (mAppsCustomizeContent != null) {                                                         
1006                 mAppsCustomizeContent.setBulkBind(false);                                                
1007             }                                                                                            
1008             mBindOnResumeCallbacks.clear();                                                              
1009             if (DEBUG_RESUME_TIME) {                                                                     
1010                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1011                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1012             }                                                                                            
1013         }                                                                                                
1014         if (mOnResumeCallbacks.size() > 0) {                                                             
1015             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1016                 mOnResumeCallbacks.get(i).run();                                                         
1017             }                                                                                            
1018             mOnResumeCallbacks.clear();                                                                  
1019         }                                                                                                
1020                                                                                                          
1021         // Reset the pressed state of icons that were locked in the press state while activities         
1022         // were launching                                                                                
1023         if (mWaitingForResume != null) {                                                                 
1024             // Resets the previous workspace icon press state                                            
1025             mWaitingForResume.setStayPressed(false);                                                     
1026         }                                                                                                
1027                                                                                                          
1028         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1029         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1030         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1031         // orientation.                                                                                  
1032         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1033                                                                                                          
1034         // Process any items that were added while Launcher was away.                                    
1035         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1036                                                                                                          
1037         // Update the voice search button proxy                                                          
1038         updateVoiceButtonProxyVisible(false);                                                            
1039                                                                                                          
1040         // Again, as with the above scenario, it's possible that one or more of the global icons         
1041         // were updated in the wrong orientation.                                                        
1042         updateGlobalIcons();                                                                             
1043         if (DEBUG_RESUME_TIME) {                                                                         
1044             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1045         }                                                                                                
1046                                                                                                          
1047         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1048             // If we are resuming and the custom content is the current page, we call onShow().          
1049             // It is also poassible that onShow will instead be called slightly after first layout       
1050             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1051             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1052                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1053             }                                                                                            
1054         }                                                                                                
1055         mWorkspace.updateInteractionForState();                                                          
1056         mWorkspace.onResume();                                                                           
1057                                                                                                          
1058         PackageInstallerCompat.getInstance(this).onResume();                                             
1059     }                                                                                                    
1060                                                                                                          
1061     @Override                                                                                            
1062     protected void onPause() {                                                                           
1063         // Ensure that items added to Launcher are queued until Launcher returns                         
1064         InstallShortcutReceiver.enableInstallQueue();                                                    
1065         PackageInstallerCompat.getInstance(this).onPause();                                              
1066                                                                                                          
1067         super.onPause();                                                                                 
1068         mPaused = true;                                                                                  
1069         mDragController.cancelDrag();                                                                    
1070         mDragController.resetLastGestureUpTime();                                                        
1071                                                                                                          
1072         // We call onHide() aggressively. The custom content callbacks should be able to                 
1073         // debounce excess onHide calls.                                                                 
1074         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1075             mWorkspace.getCustomContentCallbacks().onHide();                                             
1076         }                                                                                                
1077     }                                                                                                    
1078                                                                                                          
1079     QSBScroller mQsbScroller = new QSBScroller() {                                                       
1080         int scrollY = 0;                                                                                 
1081                                                                                                          
1082         @Override                                                                                        
1083         public void setScrollY(int scroll) {                                                             
1084             scrollY = scroll;                                                                            
1085                                                                                                          
1086             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1087                 mSearchDropTargetBar.setTranslationY(- scrollY);                                         
1088                 getQsbBar().setTranslationY(-scrollY);                                                   
1089             }                                                                                            
1090         }                                                                                                
1091     };                                                                                                   
1092                                                                                                          
1093     public void resetQSBScroll() {                                                                       
1094         mSearchDropTargetBar.animate().translationY(0).start();                                          
1095         getQsbBar().animate().translationY(0).start();                                                   
1096     }                                                                                                    
1097                                                                                                          
1098     public interface CustomContentCallbacks {                                                            
1099         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1100         // by a onResume or by scrolling otherwise.                                                      
1101         public void onShow(boolean fromResume);                                                          
1102                                                                                                          
1103         // Custom content is completely hidden                                                           
1104         public void onHide();                                                                            
1105                                                                                                          
1106         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1107         public void onScrollProgressChanged(float progress);                                             
1108                                                                                                          
1109         // Indicates whether the user is allowed to scroll away from the custom content.                 
1110         boolean isScrollingAllowed();                                                                    
1111     }                                                                                                    
1112                                                                                                          
1113     protected boolean hasSettings() {                                                                    
1114         return false;                                                                                    
1115     }                                                                                                    
1116                                                                                                          
1117     public interface QSBScroller {                                                                       
1118         public void setScrollY(int scrollY);                                                             
1119     }                                                                                                    
1120                                                                                                          
1121     public QSBScroller addToCustomContentPage(View customContent,                                        
1122             CustomContentCallbacks callbacks, String description) {                                      
1123         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1124         return mQsbScroller;                                                                             
1125     }                                                                                                    
1126                                                                                                          
1127     // The custom content needs to offset its content to account for the QSB                             
1128     public int getTopOffsetForCustomContent() {                                                          
1129         return mWorkspace.getPaddingTop();                                                               
1130     }                                                                                                    
1131                                                                                                          
1132     @Override                                                                                            
1133     public Object onRetainNonConfigurationInstance() {                                                   
1134         // Flag the loader to stop early before switching                                                
1135         if (mModel.isCurrentCallbacks(this)) {                                                           
1136             mModel.stopLoader();                                                                         
1137         }                                                                                                
1138         if (mAppsCustomizeContent != null) {                                                             
1139             mAppsCustomizeContent.surrender();                                                           
1140         }                                                                                                
1141         return Boolean.TRUE;                                                                             
1142     }                                                                                                    
1143                                                                                                          
1144     // We can't hide the IME if it was forced open.  So don't bother                                     
1145     @Override                                                                                            
1146     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1147         super.onWindowFocusChanged(hasFocus);                                                            
1148         mHasFocus = hasFocus;                                                                            
1149     }                                                                                                    
1150                                                                                                          
1151     private boolean acceptFilter() {                                                                     
1152         final InputMethodManager inputManager = (InputMethodManager)                                     
1153                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1154         return !inputManager.isFullscreenMode();                                                         
1155     }                                                                                                    
1156                                                                                                          
1157     @Override                                                                                            
1158     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1159         final int uniChar = event.getUnicodeChar();                                                      
1160         final boolean handled = super.onKeyDown(keyCode, event);                                         
1161         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1162         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1163             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1164                     keyCode, event);                                                                     
1165             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1166                 // something usable has been typed - start a search                                      
1167                 // the typed text will be retrieved and cleared by                                       
1168                 // showSearchDialog()                                                                    
1169                 // If there are multiple keystrokes before the search dialog takes focus,                
1170                 // onSearchRequested() will be called for every keystroke,                               
1171                 // but it is idempotent, so it's fine.                                                   
1172                 return onSearchRequested();                                                              
1173             }                                                                                            
1174         }                                                                                                
1175                                                                                                          
1176         // Eat the long press event so the keyboard doesn't come up.                                     
1177         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1178             return true;                                                                                 
1179         }                                                                                                
1180                                                                                                          
1181         return handled;                                                                                  
1182     }                                                                                                    
1183                                                                                                          
1184     private String getTypedText() {                                                                      
1185         return mDefaultKeySsb.toString();                                                                
1186     }                                                                                                    
1187                                                                                                          
1188     private void clearTypedText() {                                                                      
1189         mDefaultKeySsb.clear();                                                                          
1190         mDefaultKeySsb.clearSpans();                                                                     
1191         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1192     }                                                                                                    
1193                                                                                                          
1194     /**                                                                                                  
1195      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1196      * State                                                                                             
1197      */                                                                                                  
1198     private static State intToState(int stateOrdinal) {                                                  
1199         State state = State.WORKSPACE;                                                                   
1200         final State[] stateValues = State.values();                                                      
1201         for (int i = 0; i < stateValues.length; i++) {                                                   
1202             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1203                 state = stateValues[i];                                                                  
1204                 break;                                                                                   
1205             }                                                                                            
1206         }                                                                                                
1207         return state;                                                                                    
1208     }                                                                                                    
1209                                                                                                          
1210     /**                                                                                                  
1211      * Restores the previous state, if it exists.                                                        
1212      *                                                                                                   
1213      * @param savedState The previous state.                                                             
1214      */                                                                                                  
1215     @SuppressWarnings("unchecked")                                                                       
1216     private void restoreState(Bundle savedState) {                                                       
1217         if (savedState == null) {                                                                        
1218             return;                                                                                      
1219         }                                                                                                
1220                                                                                                          
1221         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1222         if (state == State.APPS_CUSTOMIZE) {                                                             
1223             mOnResumeState = State.APPS_CUSTOMIZE;                                                       
1224         }                                                                                                
1225                                                                                                          
1226         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1227                 PagedView.INVALID_RESTORE_PAGE);                                                         
1228         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1229             mWorkspace.setRestorePage(currentScreen);                                                    
1230         }                                                                                                
1231                                                                                                          
1232         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1233         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1234                                                                                                          
1235         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1236             mPendingAddInfo.container = pendingAddContainer;                                             
1237             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1238             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1239             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1240             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1241             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1242             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1243             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1244             setWaitingForResult(true);                                                                   
1245             mRestoring = true;                                                                           
1246         }                                                                                                
1247                                                                                                          
1248         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1249         if (renameFolder) {                                                                              
1250             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1251             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1252             mRestoring = true;                                                                           
1253         }                                                                                                
1254                                                                                                          
1255         // Restore the AppsCustomize tab                                                                 
1256         if (mAppsCustomizeTabHost != null) {                                                             
1257             String curTab = savedState.getString("apps_customize_currentTab");                           
1258             if (curTab != null) {                                                                        
1259                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1260                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1261                 mAppsCustomizeContent.loadAssociatedPages(                                               
1262                         mAppsCustomizeContent.getCurrentPage());                                         
1263             }                                                                                            
1264                                                                                                          
1265             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1266             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1267         }                                                                                                
1268         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1269                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1270     }                                                                                                    
1271                                                                                                          
1272     /**                                                                                                  
1273      * Finds all the views we need and configure them properly.                                          
1274      */                                                                                                  
1275     private void setupViews() {                                                                          
1276         final DragController dragController = mDragController;                                           
1277                                                                                                          
1278         mLauncherView = findViewById(R.id.launcher);                                                     
1279         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1280         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1281         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1282         mWorkspace.setPageSwitchListener(this);                                                          
1283         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1284                                                                                                          
1285         mLauncherView.setSystemUiVisibility(                                                             
1286                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1287         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1288                                                                                                          
1289         // Setup the drag layer                                                                          
1290         mDragLayer.setup(this, dragController);                                                          
1291                                                                                                          
1292         // Setup the hotseat                                                                             
1293         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1294         if (mHotseat != null) {                                                                          
1295             mHotseat.setup(this);                                                                        
1296             mHotseat.setOnLongClickListener(this);                                                       
1297         }                                                                                                
1298                                                                                                          
1299         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1300         View widgetButton = findViewById(R.id.widget_button);                                            
1301         widgetButton.setOnClickListener(new OnClickListener() {                                          
1302             @Override                                                                                    
1303             public void onClick(View arg0) {                                                             
1304                 if (!mWorkspace.isSwitchingState()) {                                                    
1305                     onClickAddWidgetButton(arg0);                                                        
1306                 }                                                                                        
1307             }                                                                                            
1308         });                                                                                              
1309         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1310                                                                                                          
1311         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1312         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1313             @Override                                                                                    
1314             public void onClick(View arg0) {                                                             
1315                 if (!mWorkspace.isSwitchingState()) {                                                    
1316                     onClickWallpaperPicker(arg0);                                                        
1317                 }                                                                                        
1318             }                                                                                            
1319         });                                                                                              
1320         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1321                                                                                                          
1322         View settingsButton = findViewById(R.id.settings_button);                                        
1323         if (hasSettings()) {                                                                             
1324             settingsButton.setOnClickListener(new OnClickListener() {                                    
1325                 @Override                                                                                
1326                 public void onClick(View arg0) {                                                         
1327                     if (!mWorkspace.isSwitchingState()) {                                                
1328                         onClickSettingsButton(arg0);                                                     
1329                     }                                                                                    
1330                 }                                                                                        
1331             });                                                                                          
1332             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1333         } else {                                                                                         
1334             settingsButton.setVisibility(View.GONE);                                                     
1335             FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();     
1336             lp.gravity = Gravity.END | Gravity.TOP;                                                      
1337             widgetButton.requestLayout();                                                                
1338         }                                                                                                
1339                                                                                                          
1340         mOverviewPanel.setAlpha(0f);                                                                     
1341                                                                                                          
1342         // Setup the workspace                                                                           
1343         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1344         mWorkspace.setOnLongClickListener(this);                                                         
1345         mWorkspace.setup(dragController);                                                                
1346         dragController.addDragListener(mWorkspace);                                                      
1347                                                                                                          
1348         // Get the search/delete bar                                                                     
1349         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1350                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1351                                                                                                          
1352         // Setup AppsCustomize                                                                           
1353         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1354         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1355                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1356         mAppsCustomizeContent.setup(this, dragController);                                               
1357                                                                                                          
1358         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1359         dragController.setDragScoller(mWorkspace);                                                       
1360         dragController.setScrollView(mDragLayer);                                                        
1361         dragController.setMoveTarget(mWorkspace);                                                        
1362         dragController.addDropTarget(mWorkspace);                                                        
1363         if (mSearchDropTargetBar != null) {                                                              
1364             mSearchDropTargetBar.setup(this, dragController);                                            
1365         }                                                                                                
1366                                                                                                          
1367         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1368             Log.v(TAG, "adding WeightWatcher");                                                          
1369             mWeightWatcher = new WeightWatcher(this);                                                    
1370             mWeightWatcher.setAlpha(0.5f);                                                               
1371             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1372                     new FrameLayout.LayoutParams(                                                        
1373                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1374                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1375                             Gravity.BOTTOM)                                                              
1376             );                                                                                           
1377                                                                                                          
1378             boolean show = shouldShowWeightWatcher();                                                    
1379             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1380         }                                                                                                
1381     }                                                                                                    
1382                                                                                                          
1383     /**                                                                                                  
1384      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1385      */                                                                                                  
1386     public void setAllAppsButton(View allAppsButton) {                                                   
1387         mAllAppsButton = allAppsButton;                                                                  
1388     }                                                                                                    
1389                                                                                                          
1390     public View getAllAppsButton() {                                                                     
1391         return mAllAppsButton;                                                                           
1392     }                                                                                                    
1393                                                                                                          
1394     /**                                                                                                  
1395      * Creates a view representing a shortcut.                                                           
1396      *                                                                                                   
1397      * @param info The data structure describing the shortcut.                                           
1398      *                                                                                                   
1399      * @return A View inflated from R.layout.application.                                                
1400      */                                                                                                  
1401     View createShortcut(ShortcutInfo info) {                                                             
1402         return createShortcut(R.layout.application,                                                      
1403                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1404     }                                                                                                    
1405                                                                                                          
1406     /**                                                                                                  
1407      * Creates a view representing a shortcut inflated from the specified resource.                      
1408      *                                                                                                   
1409      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1410      * @param parent The group the shortcut belongs to.                                                  
1411      * @param info The data structure describing the shortcut.                                           
1412      *                                                                                                   
1413      * @return A View inflated from layoutResId.                                                         
1414      */                                                                                                  
1415     View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                          
1416         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1417         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1418         favorite.setOnClickListener(this);                                                               
1419         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1420         return favorite;                                                                                 
1421     }                                                                                                    
1422                                                                                                          
1423     /**                                                                                                  
1424      * Add a shortcut to the workspace.                                                                  
1425      *                                                                                                   
1426      * @param data The intent describing the shortcut.                                                   
1427      * @param cellInfo The position on screen where to create the shortcut.                              
1428      */                                                                                                  
1429     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1430             int cellY) {                                                                                 
1431         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1432         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1433         CellLayout layout = getCellLayout(container, screenId);                                          
1434                                                                                                          
1435         boolean foundCellSpan = false;                                                                   
1436                                                                                                          
1437         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                             
1438         if (info == null) {                                                                              
1439             return;                                                                                      
1440         }                                                                                                
1441         final View view = createShortcut(info);                                                          
1442                                                                                                          
1443         // First we check if we already know the exact location where we want to add this item.          
1444         if (cellX >= 0 && cellY >= 0) {                                                                  
1445             cellXY[0] = cellX;                                                                           
1446             cellXY[1] = cellY;                                                                           
1447             foundCellSpan = true;                                                                        
1448                                                                                                          
1449             // If appropriate, either create a folder or add to an existing folder                       
1450             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1451                     true, null,null)) {                                                                  
1452                 return;                                                                                  
1453             }                                                                                            
1454             DragObject dragObject = new DragObject();                                                    
1455             dragObject.dragInfo = info;                                                                  
1456             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1457                     true)) {                                                                             
1458                 return;                                                                                  
1459             }                                                                                            
1460         } else if (touchXY != null) {                                                                    
1461             // when dragging and dropping, just find the closest free spot                               
1462             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1463             foundCellSpan = (result != null);                                                            
1464         } else {                                                                                         
1465             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1466         }                                                                                                
1467                                                                                                          
1468         if (!foundCellSpan) {                                                                            
1469             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1470             return;                                                                                      
1471         }                                                                                                
1472                                                                                                          
1473         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1474                                                                                                          
1475         if (!mRestoring) {                                                                               
1476             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1477                     isWorkspaceLocked());                                                                
1478         }                                                                                                
1479     }                                                                                                    
1480                                                                                                          
1481     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1482             int minHeight) {                                                                             
1483         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1484         // We want to account for the extra amount of padding that we are adding to the widget           
1485         // to ensure that it gets the full amount of space that it has requested                         
1486         int requiredWidth = minWidth + padding.left + padding.right;                                     
1487         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1488         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1489     }                                                                                                    
1490                                                                                                          
1491     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1492         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1493     }                                                                                                    
1494                                                                                                          
1495     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1496         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1497     }                                                                                                    
1498                                                                                                          
1499     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1500         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1501     }                                                                                                    
1502                                                                                                          
1503     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1504         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1505                 info.minResizeHeight);                                                                   
1506     }                                                                                                    
1507                                                                                                          
1508     /**                                                                                                  
1509      * Add a widget to the workspace.                                                                    
1510      *                                                                                                   
1511      * @param appWidgetId The app widget id                                                              
1512      * @param cellInfo The position on screen where to create the widget.                                
1513      */                                                                                                  
1514     private void completeAddAppWidget(final int appWidgetId, long container, long screenId,              
1515             AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                           
1516         if (appWidgetInfo == null) {                                                                     
1517             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
1518         }                                                                                                
1519                                                                                                          
1520         // Calculate the grid spans needed to fit this widget                                            
1521         CellLayout layout = getCellLayout(container, screenId);                                          
1522                                                                                                          
1523         int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                      
1524         int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                            
1525                                                                                                          
1526         // Try finding open space on Launcher screen                                                     
1527         // We have saved the position to which the widget was dragged-- this really only matters         
1528         // if we are placing widgets on a "spring-loaded" screen                                         
1529         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1530         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1531         int[] finalSpan = new int[2];                                                                    
1532         boolean foundCellSpan = false;                                                                   
1533         if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                  
1534             cellXY[0] = mPendingAddInfo.cellX;                                                           
1535             cellXY[1] = mPendingAddInfo.cellY;                                                           
1536             spanXY[0] = mPendingAddInfo.spanX;                                                           
1537             spanXY[1] = mPendingAddInfo.spanY;                                                           
1538             foundCellSpan = true;                                                                        
1539         } else if (touchXY != null) {                                                                    
1540             // when dragging and dropping, just find the closest free spot                               
1541             int[] result = layout.findNearestVacantArea(                                                 
1542                     touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                       
1543                     spanXY[1], cellXY, finalSpan);                                                       
1544             spanXY[0] = finalSpan[0];                                                                    
1545             spanXY[1] = finalSpan[1];                                                                    
1546             foundCellSpan = (result != null);                                                            
1547         } else {                                                                                         
1548             foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                  
1549         }                                                                                                
1550                                                                                                          
1551         if (!foundCellSpan) {                                                                            
1552             if (appWidgetId != -1) {                                                                     
1553                 // Deleting an app widget ID is a void call but writes to disk before returning          
1554                 // to the caller...                                                                      
1555                 new AsyncTask<Void, Void, Void>() {                                                      
1556                     public Void doInBackground(Void ... args) {                                          
1557                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                   
1558                         return null;                                                                     
1559                     }                                                                                    
1560                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                        
1561             }                                                                                            
1562             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1563             return;                                                                                      
1564         }                                                                                                
1565                                                                                                          
1566         // Build Launcher-specific widget info and save to database                                      
1567         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                      
1568                 appWidgetInfo.provider);                                                                 
1569         launcherInfo.spanX = spanXY[0];                                                                  
1570         launcherInfo.spanY = spanXY[1];                                                                  
1571         launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                
1572         launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                
1573         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1574                                                                                                          
1575         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1576                 container, screenId, cellXY[0], cellXY[1], false);                                       
1577                                                                                                          
1578         if (!mRestoring) {                                                                               
1579             if (hostView == null) {                                                                      
1580                 // Perform actual inflation because we're live                                           
1581                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1582                 launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                          
1583             } else {                                                                                     
1584                 // The AppWidgetHostView has already been inflated and instantiated                      
1585                 launcherInfo.hostView = hostView;                                                        
1586             }                                                                                            
1587                                                                                                          
1588             launcherInfo.hostView.setTag(launcherInfo);                                                  
1589             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1590             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1591                                                                                                          
1592             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],     
1593                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                        
1594                                                                                                          
1595             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1596         }                                                                                                
1597         resetAddInfo();                                                                                  
1598     }                                                                                                    
1599                                                                                                          
1600     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1601         @Override                                                                                        
1602         public void onReceive(Context context, Intent intent) {                                          
1603             final String action = intent.getAction();                                                    
1604             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1605                 mUserPresent = false;                                                                    
1606                 mDragLayer.clearAllResizeFrames();                                                       
1607                 updateRunning();                                                                         
1608                                                                                                          
1609                 // Reset AllApps to its initial state only if we are not in the middle of                
1610                 // processing a multi-step drop                                                          
1611                 if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {      
1612                     showWorkspace(false);                                                                
1613                 }                                                                                        
1614             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1615                 mUserPresent = true;                                                                     
1616                 updateRunning();                                                                         
1617             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1618                 mModel.resetLoadedState(false, true);                                                    
1619                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1620                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1621             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1622                 mModel.resetLoadedState(false, true);                                                    
1623                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1624                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1625                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1626             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1627                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1628                 getModel().forceReload();                                                                
1629             }                                                                                            
1630         }                                                                                                
1631     };                                                                                                   
1632                                                                                                          
1633     @Override                                                                                            
1634     public void onAttachedToWindow() {                                                                   
1635         super.onAttachedToWindow();                                                                      
1636                                                                                                          
1637         // Listen for broadcasts related to user-presence                                                
1638         final IntentFilter filter = new IntentFilter();                                                  
1639         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1640         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1641         // For handling managed profiles                                                                 
1642         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1643         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1644         if (ENABLE_DEBUG_INTENTS) {                                                                      
1645             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1646             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1647         }                                                                                                
1648         registerReceiver(mReceiver, filter);                                                             
1649         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1650         setupTransparentSystemBarsForLmp();                                                              
1651         mAttached = true;                                                                                
1652         mVisible = true;                                                                                 
1653     }                                                                                                    
1654                                                                                                          
1655     /**                                                                                                  
1656      * Sets up transparent navigation and status bars in LMP.                                            
1657      * This method is a no-op for other platform versions.                                               
1658      */                                                                                                  
1659     @TargetApi(19)                                                                                       
1660     private void setupTransparentSystemBarsForLmp() {                                                    
1661         // TODO(sansid): use the APIs directly when compiling against L sdk.                             
1662         // Currently we use reflection to access the flags and the API to set the transparency           
1663         // on the System bars.                                                                           
1664         if (Utilities.isLmpOrAbove()) {                                                                  
1665             try {                                                                                        
1666                 getWindow().getAttributes().systemUiVisibility |=                                        
1667                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1668                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1669                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1670                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                
1671                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1672                 Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(              
1673                         "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                            
1674                 getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                             
1675                                                                                                          
1676                 Method setStatusBarColorMethod =                                                         
1677                         Window.class.getDeclaredMethod("setStatusBarColor", int.class);                  
1678                 Method setNavigationBarColorMethod =                                                     
1679                         Window.class.getDeclaredMethod("setNavigationBarColor", int.class);              
1680                 setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                          
1681                 setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                      
1682             } catch (NoSuchFieldException e) {                                                           
1683                 Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                    
1684             } catch (NoSuchMethodException ex) {                                                         
1685                 Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                   
1686             } catch (IllegalAccessException e) {                                                         
1687                 Log.w(TAG, "IllegalAccessException while setting up transparent bars");                  
1688             } catch (IllegalArgumentException e) {                                                       
1689                 Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                
1690             } catch (InvocationTargetException e) {                                                      
1691                 Log.w(TAG, "InvocationTargetException while setting up transparent bars");               
1692             } finally {}                                                                                 
1693         }                                                                                                
1694     }                                                                                                    
1695                                                                                                          
1696     @Override                                                                                            
1697     public void onDetachedFromWindow() {                                                                 
1698         super.onDetachedFromWindow();                                                                    
1699         mVisible = false;                                                                                
1700                                                                                                          
1701         if (mAttached) {                                                                                 
1702             unregisterReceiver(mReceiver);                                                               
1703             mAttached = false;                                                                           
1704         }                                                                                                
1705         updateRunning();                                                                                 
1706     }                                                                                                    
1707                                                                                                          
1708     public void onWindowVisibilityChanged(int visibility) {                                              
1709         mVisible = visibility == View.VISIBLE;                                                           
1710         updateRunning();                                                                                 
1711         // The following code used to be in onResume, but it turns out onResume is called when           
1712         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1713         // is a more appropriate event to handle                                                         
1714         if (mVisible) {                                                                                  
1715             mAppsCustomizeTabHost.onWindowVisible();                                                     
1716             if (!mWorkspaceLoading) {                                                                    
1717                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1718                 // We want to let Launcher draw itself at least once before we force it to build         
1719                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1720                 // apps is nice and speedy.                                                              
1721                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1722                     private boolean mStarted = false;                                                    
1723                     public void onDraw() {                                                               
1724                         if (mStarted) return;                                                            
1725                         mStarted = true;                                                                 
1726                         // We delay the layer building a bit in order to give                            
1727                         // other message processing a time to run.  In particular                        
1728                         // this avoids a delay in hiding the IME if it was                               
1729                         // currently shown, because doing that may involve                               
1730                         // some communication back with the app.                                         
1731                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1732                         final ViewTreeObserver.OnDrawListener listener = this;                           
1733                         mWorkspace.post(new Runnable() {                                                 
1734                                 public void run() {                                                      
1735                                     if (mWorkspace != null &&                                            
1736                                             mWorkspace.getViewTreeObserver() != null) {                  
1737                                         mWorkspace.getViewTreeObserver().                                
1738                                                 removeOnDrawListener(listener);                          
1739                                     }                                                                    
1740                                 }                                                                        
1741                             });                                                                          
1742                         return;                                                                          
1743                     }                                                                                    
1744                 });                                                                                      
1745             }                                                                                            
1746             clearTypedText();                                                                            
1747         }                                                                                                
1748     }                                                                                                    
1749                                                                                                          
1750     private void sendAdvanceMessage(long delay) {                                                        
1751         mHandler.removeMessages(ADVANCE_MSG);                                                            
1752         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1753         mHandler.sendMessageDelayed(msg, delay);                                                         
1754         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1755     }                                                                                                    
1756                                                                                                          
1757     private void updateRunning() {                                                                       
1758         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1759         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1760             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1761             if (autoAdvanceRunning) {                                                                    
1762                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1763                 sendAdvanceMessage(delay);                                                               
1764             } else {                                                                                     
1765                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1766                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1767                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1768                 }                                                                                        
1769                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1770                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1771             }                                                                                            
1772         }                                                                                                
1773     }                                                                                                    
1774                                                                                                          
1775     private final Handler mHandler = new Handler() {                                                     
1776         @Override                                                                                        
1777         public void handleMessage(Message msg) {                                                         
1778             if (msg.what == ADVANCE_MSG) {                                                               
1779                 int i = 0;                                                                               
1780                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1781                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1782                     final int delay = mAdvanceStagger * i;                                               
1783                     if (v instanceof Advanceable) {                                                      
1784                        postDelayed(new Runnable() {                                                      
1785                            public void run() {                                                           
1786                                ((Advanceable) v).advance();                                              
1787                            }                                                                             
1788                        }, delay);                                                                        
1789                     }                                                                                    
1790                     i++;                                                                                 
1791                 }                                                                                        
1792                 sendAdvanceMessage(mAdvanceInterval);                                                    
1793             }                                                                                            
1794         }                                                                                                
1795     };                                                                                                   
1796                                                                                                          
1797     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1798         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1799         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1800         if (v instanceof Advanceable) {                                                                  
1801             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1802             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1803             updateRunning();                                                                             
1804         }                                                                                                
1805     }                                                                                                    
1806                                                                                                          
1807     void removeWidgetToAutoAdvance(View hostView) {                                                      
1808         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1809             mWidgetsToAdvance.remove(hostView);                                                          
1810             updateRunning();                                                                             
1811         }                                                                                                
1812     }                                                                                                    
1813                                                                                                          
1814     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1815         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1816         launcherInfo.hostView = null;                                                                    
1817     }                                                                                                    
1818                                                                                                          
1819     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1820         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1821         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1822     }                                                                                                    
1823                                                                                                          
1824     public DragLayer getDragLayer() {                                                                    
1825         return mDragLayer;                                                                               
1826     }                                                                                                    
1827                                                                                                          
1828     public Workspace getWorkspace() {                                                                    
1829         return mWorkspace;                                                                               
1830     }                                                                                                    
1831                                                                                                          
1832     public Hotseat getHotseat() {                                                                        
1833         return mHotseat;                                                                                 
1834     }                                                                                                    
1835                                                                                                          
1836     public ViewGroup getOverviewPanel() {                                                                
1837         return mOverviewPanel;                                                                           
1838     }                                                                                                    
1839                                                                                                          
1840     public SearchDropTargetBar getSearchBar() {                                                          
1841         return mSearchDropTargetBar;                                                                     
1842     }                                                                                                    
1843                                                                                                          
1844     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1845         return mAppWidgetHost;                                                                           
1846     }                                                                                                    
1847                                                                                                          
1848     public LauncherModel getModel() {                                                                    
1849         return mModel;                                                                                   
1850     }                                                                                                    
1851                                                                                                          
1852     protected SharedPreferences getSharedPrefs() {                                                       
1853         return mSharedPrefs;                                                                             
1854     }                                                                                                    
1855                                                                                                          
1856     public void closeSystemDialogs() {                                                                   
1857         getWindow().closeAllPanels();                                                                    
1858                                                                                                          
1859         // Whatever we were doing is hereby canceled.                                                    
1860         setWaitingForResult(false);                                                                      
1861     }                                                                                                    
1862                                                                                                          
1863     @Override                                                                                            
1864     protected void onNewIntent(Intent intent) {                                                          
1865         long startTime = 0;                                                                              
1866         if (DEBUG_RESUME_TIME) {                                                                         
1867             startTime = System.currentTimeMillis();                                                      
1868         }                                                                                                
1869         super.onNewIntent(intent);                                                                       
1870                                                                                                          
1871         // Close the menu                                                                                
1872         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1873             // also will cancel mWaitingForResult.                                                       
1874             closeSystemDialogs();                                                                        
1875                                                                                                          
1876             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1877                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1878                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1879                                                                                                          
1880             if (mWorkspace == null) {                                                                    
1881                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1882                 return;                                                                                  
1883             }                                                                                            
1884             Folder openFolder = mWorkspace.getOpenFolder();                                              
1885             // In all these cases, only animate if we're already on home                                 
1886             mWorkspace.exitWidgetResizeMode();                                                           
1887             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1888                     openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                     
1889                 mWorkspace.moveToDefaultScreen(true);                                                    
1890             }                                                                                            
1891                                                                                                          
1892             closeFolder();                                                                               
1893             exitSpringLoadedDragMode();                                                                  
1894                                                                                                          
1895             // If we are already on home, then just animate back to the workspace,                       
1896             // otherwise, just wait until onResume to set the state back to Workspace                    
1897             if (alreadyOnHome) {                                                                         
1898                 showWorkspace(true);                                                                     
1899             } else {                                                                                     
1900                 mOnResumeState = State.WORKSPACE;                                                        
1901             }                                                                                            
1902                                                                                                          
1903             final View v = getWindow().peekDecorView();                                                  
1904             if (v != null && v.getWindowToken() != null) {                                               
1905                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1906                         INPUT_METHOD_SERVICE);                                                           
1907                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1908             }                                                                                            
1909                                                                                                          
1910             // Reset the apps customize page                                                             
1911             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1912                 mAppsCustomizeTabHost.reset();                                                           
1913             }                                                                                            
1914                                                                                                          
1915             onHomeIntent();                                                                              
1916         }                                                                                                
1917                                                                                                          
1918         if (DEBUG_RESUME_TIME) {                                                                         
1919             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1920         }                                                                                                
1921     }                                                                                                    
1922                                                                                                          
1923     /**                                                                                                  
1924      * Override point for subclasses to prevent movement to the default screen when the home             
1925      * button is pressed. Used (for example) in GEL, to prevent movement during a search.                
1926      */                                                                                                  
1927     protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                          
1928         return true;                                                                                     
1929     }                                                                                                    
1930                                                                                                          
1931     /**                                                                                                  
1932      * Override point for subclasses to provide custom behaviour for when a home intent is fired.        
1933      */                                                                                                  
1934     protected void onHomeIntent() {                                                                      
1935         // Do nothing                                                                                    
1936     }                                                                                                    
1937                                                                                                          
1938     @Override                                                                                            
1939     public void onRestoreInstanceState(Bundle state) {                                                   
1940         super.onRestoreInstanceState(state);                                                             
1941         for (int page: mSynchronouslyBoundPages) {                                                       
1942             mWorkspace.restoreInstanceStateForChild(page);                                               
1943         }                                                                                                
1944     }                                                                                                    
1945                                                                                                          
1946     @Override                                                                                            
1947     protected void onSaveInstanceState(Bundle outState) {                                                
1948         if (mWorkspace.getChildCount() > 0) {                                                            
1949             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1950                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1951         }                                                                                                
1952         super.onSaveInstanceState(outState);                                                             
1953                                                                                                          
1954         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1955         // We close any open folder since it will not be re-opened, and we need to make sure             
1956         // this state is reflected.                                                                      
1957         closeFolder();                                                                                   
1958                                                                                                          
1959         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1960                 mWaitingForResult) {                                                                     
1961             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1962             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1963             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1964             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1965             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1966             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1967             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1968             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1969         }                                                                                                
1970                                                                                                          
1971         if (mFolderInfo != null && mWaitingForResult) {                                                  
1972             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
1973             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
1974         }                                                                                                
1975                                                                                                          
1976         // Save the current AppsCustomize tab                                                            
1977         if (mAppsCustomizeTabHost != null) {                                                             
1978             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
1979             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
1980             if (currentTabTag != null) {                                                                 
1981                 outState.putString("apps_customize_currentTab", currentTabTag);                          
1982             }                                                                                            
1983             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
1984             outState.putInt("apps_customize_currentIndex", currentIndex);                                
1985         }                                                                                                
1986         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1987     }                                                                                                    
1988                                                                                                          
1989     @Override                                                                                            
1990     public void onDestroy() {                                                                            
1991         super.onDestroy();                                                                               
1992                                                                                                          
1993         // Remove all pending runnables                                                                  
1994         mHandler.removeMessages(ADVANCE_MSG);                                                            
1995         mHandler.removeMessages(0);                                                                      
1996         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
1997                                                                                                          
1998         // Stop callbacks from LauncherModel                                                             
1999         LauncherAppState app = (LauncherAppState.getInstance());                                         
2000                                                                                                          
2001         // It's possible to receive onDestroy after a new Launcher activity has                          
2002         // been created. In this case, don't interfere with the new Launcher.                            
2003         if (mModel.isCurrentCallbacks(this)) {                                                           
2004             mModel.stopLoader();                                                                         
2005             app.setLauncher(null);                                                                       
2006         }                                                                                                
2007                                                                                                          
2008         try {                                                                                            
2009             mAppWidgetHost.stopListening();                                                              
2010         } catch (NullPointerException ex) {                                                              
2011             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2012         }                                                                                                
2013         mAppWidgetHost = null;                                                                           
2014                                                                                                          
2015         mWidgetsToAdvance.clear();                                                                       
2016                                                                                                          
2017         TextKeyListener.getInstance().release();                                                         
2018                                                                                                          
2019         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2020         // to prevent leaking Launcher activities on orientation change.                                 
2021         if (mModel != null) {                                                                            
2022             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2023         }                                                                                                
2024                                                                                                          
2025         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2026         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2027                                                                                                          
2028         mDragLayer.clearAllResizeFrames();                                                               
2029         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2030         mWorkspace.removeAllWorkspaceScreens();                                                          
2031         mWorkspace = null;                                                                               
2032         mDragController = null;                                                                          
2033                                                                                                          
2034         PackageInstallerCompat.getInstance(this).onStop();                                               
2035         LauncherAnimUtils.onDestroyActivity();                                                           
2036     }                                                                                                    
2037                                                                                                          
2038     public DragController getDragController() {                                                          
2039         return mDragController;                                                                          
2040     }                                                                                                    
2041                                                                                                          
2042     @Override                                                                                            
2043     public void startActivityForResult(Intent intent, int requestCode) {                                 
2044         if (requestCode >= 0) {                                                                          
2045             setWaitingForResult(true);                                                                   
2046         }                                                                                                
2047         super.startActivityForResult(intent, requestCode);                                               
2048     }                                                                                                    
2049                                                                                                          
2050     /**                                                                                                  
2051      * Indicates that we want global search for this activity by setting the globalSearch                
2052      * argument for {@link #startSearch} to true.                                                        
2053      */                                                                                                  
2054     @Override                                                                                            
2055     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2056             Bundle appSearchData, boolean globalSearch) {                                                
2057                                                                                                          
2058         showWorkspace(true);                                                                             
2059                                                                                                          
2060         if (initialQuery == null) {                                                                      
2061             // Use any text typed in the launcher as the initial query                                   
2062             initialQuery = getTypedText();                                                               
2063         }                                                                                                
2064         if (appSearchData == null) {                                                                     
2065             appSearchData = new Bundle();                                                                
2066             appSearchData.putString("source", "launcher-search");                                        
2067         }                                                                                                
2068         Rect sourceBounds = new Rect();                                                                  
2069         if (mSearchDropTargetBar != null) {                                                              
2070             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2071         }                                                                                                
2072                                                                                                          
2073         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2074                 appSearchData, sourceBounds);                                                            
2075         if (clearTextImmediately) {                                                                      
2076             clearTypedText();                                                                            
2077         }                                                                                                
2078     }                                                                                                    
2079                                                                                                          
2080     /**                                                                                                  
2081      * Start a text search.                                                                              
2082      *                                                                                                   
2083      * @return {@code true} if the search will start immediately, so any further keypresses              
2084      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2085      * to buffer keypresses.                                                                             
2086      */                                                                                                  
2087     public boolean startSearch(String initialQuery,                                                      
2088             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2089         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2090                 appSearchData, sourceBounds);                                                            
2091         return false;                                                                                    
2092     }                                                                                                    
2093                                                                                                          
2094     /**                                                                                                  
2095      * Starts the global search activity. This code is a copied from SearchManager                       
2096      */                                                                                                  
2097     private void startGlobalSearch(String initialQuery,                                                  
2098             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2099         final SearchManager searchManager =                                                              
2100             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2101         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2102         if (globalSearchActivity == null) {                                                              
2103             Log.w(TAG, "No global search activity found.");                                              
2104             return;                                                                                      
2105         }                                                                                                
2106         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2107         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2108         intent.setComponent(globalSearchActivity);                                                       
2109         // Make sure that we have a Bundle to put source in                                              
2110         if (appSearchData == null) {                                                                     
2111             appSearchData = new Bundle();                                                                
2112         } else {                                                                                         
2113             appSearchData = new Bundle(appSearchData);                                                   
2114         }                                                                                                
2115         // Set source to package name of app that starts global search, if not set already.              
2116         if (!appSearchData.containsKey("source")) {                                                      
2117             appSearchData.putString("source", getPackageName());                                         
2118         }                                                                                                
2119         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2120         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2121             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2122         }                                                                                                
2123         if (selectInitialQuery) {                                                                        
2124             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2125         }                                                                                                
2126         intent.setSourceBounds(sourceBounds);                                                            
2127         try {                                                                                            
2128             startActivity(intent);                                                                       
2129         } catch (ActivityNotFoundException ex) {                                                         
2130             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2131         }                                                                                                
2132     }                                                                                                    
2133                                                                                                          
2134     public boolean isOnCustomContent() {                                                                 
2135         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2136     }                                                                                                    
2137                                                                                                          
2138     @Override                                                                                            
2139     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2140         super.onPrepareOptionsMenu(menu);                                                                
2141         if (!isOnCustomContent()) {                                                                      
2142             // Close any open folders                                                                    
2143             closeFolder();                                                                               
2144             // Stop resizing any widgets                                                                 
2145             mWorkspace.exitWidgetResizeMode();                                                           
2146             if (!mWorkspace.isInOverviewMode()) {                                                        
2147                 // Show the overview mode                                                                
2148                 showOverviewMode(true);                                                                  
2149             } else {                                                                                     
2150                 showWorkspace(true);                                                                     
2151             }                                                                                            
2152         }                                                                                                
2153         return false;                                                                                    
2154     }                                                                                                    
2155                                                                                                          
2156     @Override                                                                                            
2157     public boolean onSearchRequested() {                                                                 
2158         startSearch(null, false, null, true);                                                            
2159         // Use a custom animation for launching search                                                   
2160         return true;                                                                                     
2161     }                                                                                                    
2162                                                                                                          
2163     public boolean isWorkspaceLocked() {                                                                 
2164         return mWorkspaceLoading || mWaitingForResult;                                                   
2165     }                                                                                                    
2166                                                                                                          
2167     public boolean isWorkspaceLoading() {                                                                
2168         return mWorkspaceLoading;                                                                        
2169     }                                                                                                    
2170                                                                                                          
2171     private void setWorkspaceLoading(boolean value) {                                                    
2172         boolean isLocked = isWorkspaceLocked();                                                          
2173         mWorkspaceLoading = value;                                                                       
2174         if (isLocked != isWorkspaceLocked()) {                                                           
2175             onWorkspaceLockedChanged();                                                                  
2176         }                                                                                                
2177     }                                                                                                    
2178                                                                                                          
2179     private void setWaitingForResult(boolean value) {                                                    
2180         boolean isLocked = isWorkspaceLocked();                                                          
2181         mWaitingForResult = value;                                                                       
2182         if (isLocked != isWorkspaceLocked()) {                                                           
2183             onWorkspaceLockedChanged();                                                                  
2184         }                                                                                                
2185     }                                                                                                    
2186                                                                                                          
2187     protected void onWorkspaceLockedChanged() { }                                                        
2188                                                                                                          
2189     private void resetAddInfo() {                                                                        
2190         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2191         mPendingAddInfo.screenId = -1;                                                                   
2192         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2193         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2194         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2195         mPendingAddInfo.dropPos = null;                                                                  
2196     }                                                                                                    
2197                                                                                                          
2198     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2199             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2200         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2201     }                                                                                                    
2202                                                                                                          
2203     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2204             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int          
2205             delay) {                                                                                     
2206         if (appWidgetInfo.configure != null) {                                                           
2207             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2208             mPendingAddWidgetId = appWidgetId;                                                           
2209                                                                                                          
2210             // Launch over to configure widget, if needed                                                
2211             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2212                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2213                                                                                                          
2214         } else {                                                                                         
2215             // Otherwise just add it                                                                     
2216             Runnable onComplete = new Runnable() {                                                       
2217                 @Override                                                                                
2218                 public void run() {                                                                      
2219                     // Exit spring loaded mode if necessary after adding the widget                      
2220                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2221                             null);                                                                       
2222                 }                                                                                        
2223             };                                                                                           
2224             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2225                     appWidgetInfo);                                                                      
2226             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2227         }                                                                                                
2228     }                                                                                                    
2229                                                                                                          
2230     protected void moveToCustomContentScreen(boolean animate) {                                          
2231         // Close any folders that may be open.                                                           
2232         closeFolder();                                                                                   
2233         mWorkspace.moveToCustomContentScreen(animate);                                                   
2234     }                                                                                                    
2235     /**                                                                                                  
2236      * Process a shortcut drop.                                                                          
2237      *                                                                                                   
2238      * @param componentName The name of the component                                                    
2239      * @param screenId The ID of the screen where it should be added                                     
2240      * @param cell The cell it should be added to, optional                                              
2241      * @param position The location on the screen where it was dropped, optional                         
2242      */                                                                                                  
2243     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2244             int[] cell, int[] loc) {                                                                     
2245         resetAddInfo();                                                                                  
2246         mPendingAddInfo.container = container;                                                           
2247         mPendingAddInfo.screenId = screenId;                                                             
2248         mPendingAddInfo.dropPos = loc;                                                                   
2249                                                                                                          
2250         if (cell != null) {                                                                              
2251             mPendingAddInfo.cellX = cell[0];                                                             
2252             mPendingAddInfo.cellY = cell[1];                                                             
2253         }                                                                                                
2254                                                                                                          
2255         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2256         createShortcutIntent.setComponent(componentName);                                                
2257         processShortcut(createShortcutIntent);                                                           
2258     }                                                                                                    
2259                                                                                                          
2260     /**                                                                                                  
2261      * Process a widget drop.                                                                            
2262      *                                                                                                   
2263      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2264      * @param screenId The ID of the screen where it should be added                                     
2265      * @param cell The cell it should be added to, optional                                              
2266      * @param position The location on the screen where it was dropped, optional                         
2267      */                                                                                                  
2268     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                  
2269             int[] cell, int[] span, int[] loc) {                                                         
2270         resetAddInfo();                                                                                  
2271         mPendingAddInfo.container = info.container = container;                                          
2272         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2273         mPendingAddInfo.dropPos = loc;                                                                   
2274         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2275         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2276                                                                                                          
2277         if (cell != null) {                                                                              
2278             mPendingAddInfo.cellX = cell[0];                                                             
2279             mPendingAddInfo.cellY = cell[1];                                                             
2280         }                                                                                                
2281         if (span != null) {                                                                              
2282             mPendingAddInfo.spanX = span[0];                                                             
2283             mPendingAddInfo.spanY = span[1];                                                             
2284         }                                                                                                
2285                                                                                                          
2286         AppWidgetHostView hostView = info.boundWidget;                                                   
2287         int appWidgetId;                                                                                 
2288         if (hostView != null) {                                                                          
2289             appWidgetId = hostView.getAppWidgetId();                                                     
2290             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2291         } else {                                                                                         
2292             // In this case, we either need to start an activity to get permission to bind               
2293             // the widget, or we need to start an activity to configure the widget, or both.             
2294             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2295             Bundle options = info.bindOptions;                                                           
2296                                                                                                          
2297             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2298                     appWidgetId, info.info, options);                                                    
2299             if (success) {                                                                               
2300                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2301             } else {                                                                                     
2302                 mPendingAddWidgetInfo = info.info;                                                       
2303                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2304                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2305                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2306                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2307                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2308                 // TODO: we need to make sure that this accounts for the options bundle.                 
2309                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2310                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2311             }                                                                                            
2312         }                                                                                                
2313     }                                                                                                    
2314                                                                                                          
2315     void processShortcut(Intent intent) {                                                                
2316         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2317     }                                                                                                    
2318                                                                                                          
2319     void processWallpaper(Intent intent) {                                                               
2320         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2321     }                                                                                                    
2322                                                                                                          
2323     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2324             int cellY) {                                                                                 
2325         final FolderInfo folderInfo = new FolderInfo();                                                  
2326         folderInfo.title = getText(R.string.folder_name);                                                
2327                                                                                                          
2328         // Update the model                                                                              
2329         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2330                 false);                                                                                  
2331         sFolders.put(folderInfo.id, folderInfo);                                                         
2332                                                                                                          
2333         // Create the view                                                                               
2334         FolderIcon newFolder =                                                                           
2335             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2336         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2337                 isWorkspaceLocked());                                                                    
2338         // Force measure the new folder icon                                                             
2339         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2340         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2341         return newFolder;                                                                                
2342     }                                                                                                    
2343                                                                                                          
2344     void removeFolder(FolderInfo folder) {                                                               
2345         sFolders.remove(folder.id);                                                                      
2346     }                                                                                                    
2347                                                                                                          
2348     protected ComponentName getWallpaperPickerComponent() {                                              
2349         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2350     }                                                                                                    
2351                                                                                                          
2352     /**                                                                                                  
2353      * Registers various content observers. The current implementation registers                         
2354      * only a favorites observer to keep track of the favorites applications.                            
2355      */                                                                                                  
2356     private void registerContentObservers() {                                                            
2357         ContentResolver resolver = getContentResolver();                                                 
2358         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2359                 true, mWidgetObserver);                                                                  
2360     }                                                                                                    
2361                                                                                                          
2362     @Override                                                                                            
2363     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2364         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2365             switch (event.getKeyCode()) {                                                                
2366                 case KeyEvent.KEYCODE_HOME:                                                              
2367                     return true;                                                                         
2368                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2369                     if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                        
2370                         dumpState();                                                                     
2371                         return true;                                                                     
2372                     }                                                                                    
2373                     break;                                                                               
2374             }                                                                                            
2375         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2376             switch (event.getKeyCode()) {                                                                
2377                 case KeyEvent.KEYCODE_HOME:                                                              
2378                     return true;                                                                         
2379             }                                                                                            
2380         }                                                                                                
2381                                                                                                          
2382         return super.dispatchKeyEvent(event);                                                            
2383     }                                                                                                    
2384                                                                                                          
2385     @Override                                                                                            
2386     public void onBackPressed() {                                                                        
2387         if (isAllAppsVisible()) {                                                                        
2388             if (mAppsCustomizeContent.getContentType() ==                                                
2389                     AppsCustomizePagedView.ContentType.Applications) {                                   
2390                 showWorkspace(true);                                                                     
2391             } else {                                                                                     
2392                 showOverviewMode(true);                                                                  
2393             }                                                                                            
2394         } else if (mWorkspace.isInOverviewMode()) {                                                      
2395             mWorkspace.exitOverviewMode(true);                                                           
2396         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2397             Folder openFolder = mWorkspace.getOpenFolder();                                              
2398             if (openFolder.isEditingName()) {                                                            
2399                 openFolder.dismissEditingName();                                                         
2400             } else {                                                                                     
2401                 closeFolder();                                                                           
2402             }                                                                                            
2403         } else {                                                                                         
2404             mWorkspace.exitWidgetResizeMode();                                                           
2405                                                                                                          
2406             // Back button is a no-op here, but give at least some feedback for the button press         
2407             mWorkspace.showOutlinesTemporarily();                                                        
2408         }                                                                                                
2409     }                                                                                                    
2410                                                                                                          
2411     /**                                                                                                  
2412      * Re-listen when widgets are reset.                                                                 
2413      */                                                                                                  
2414     private void onAppWidgetReset() {                                                                    
2415         if (mAppWidgetHost != null) {                                                                    
2416             mAppWidgetHost.startListening();                                                             
2417         }                                                                                                
2418     }                                                                                                    
2419                                                                                                          
2420     /**                                                                                                  
2421      * Launches the intent referred by the clicked shortcut.                                             
2422      *                                                                                                   
2423      * @param v The view representing the clicked shortcut.                                              
2424      */                                                                                                  
2425     public void onClick(View v) {                                                                        
2426         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2427         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2428         if (v.getWindowToken() == null) {                                                                
2429             return;                                                                                      
2430         }                                                                                                
2431                                                                                                          
2432         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2433             return;                                                                                      
2434         }                                                                                                
2435                                                                                                          
2436         if (v instanceof Workspace) {                                                                    
2437             if (mWorkspace.isInOverviewMode()) {                                                         
2438                 mWorkspace.exitOverviewMode(true);                                                       
2439             }                                                                                            
2440             return;                                                                                      
2441         }                                                                                                
2442                                                                                                          
2443         if (v instanceof CellLayout) {                                                                   
2444             if (mWorkspace.isInOverviewMode()) {                                                         
2445                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2446             }                                                                                            
2447         }                                                                                                
2448                                                                                                          
2449         Object tag = v.getTag();                                                                         
2450         if (tag instanceof ShortcutInfo) {                                                               
2451             onClickAppShortcut(v);                                                                       
2452         } else if (tag instanceof FolderInfo) {                                                          
2453             if (v instanceof FolderIcon) {                                                               
2454                 onClickFolderIcon(v);                                                                    
2455             }                                                                                            
2456         } else if (v == mAllAppsButton) {                                                                
2457             onClickAllAppsButton(v);                                                                     
2458         } else if (tag instanceof AppInfo) {                                                             
2459             startAppShortcutOrInfoActivity(v);                                                           
2460         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2461             if (v instanceof PendingAppWidgetHostView) {                                                 
2462                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2463             }                                                                                            
2464         }                                                                                                
2465     }                                                                                                    
2466                                                                                                          
2467     public void onClickPagedViewIcon(View v) {                                                           
2468         startAppShortcutOrInfoActivity(v);                                                               
2469     }                                                                                                    
2470                                                                                                          
2471     public boolean onTouch(View v, MotionEvent event) {                                                  
2472         return false;                                                                                    
2473     }                                                                                                    
2474                                                                                                          
2475     /**                                                                                                  
2476      * Event handler for the app widget view which has not fully restored.                               
2477      */                                                                                                  
2478     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2479         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2480         if (v.isReadyForClickSetup()) {                                                                  
2481             int widgetId = info.appWidgetId;                                                             
2482             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2483             if (appWidgetInfo != null) {                                                                 
2484                 mPendingAddWidgetInfo = appWidgetInfo;                                                   
2485                 mPendingAddInfo.copyFrom(info);                                                          
2486                 mPendingAddWidgetId = widgetId;                                                          
2487                                                                                                          
2488                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2489                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2490             }                                                                                            
2491         } else if (info.installProgress < 0) {                                                           
2492             // The install has not been queued                                                           
2493             final String packageName = info.providerName.getPackageName();                               
2494             showBrokenAppInstallDialog(packageName,                                                      
2495                 new DialogInterface.OnClickListener() {                                                  
2496                     public void onClick(DialogInterface dialog, int id) {                                
2497                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2498                     }                                                                                    
2499                 });                                                                                      
2500         } else {                                                                                         
2501             // Download has started.                                                                     
2502             final String packageName = info.providerName.getPackageName();                               
2503             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2504         }                                                                                                
2505     }                                                                                                    
2506                                                                                                          
2507     /**                                                                                                  
2508      * Event handler for the search button                                                               
2509      *                                                                                                   
2510      * @param v The view that was clicked.                                                               
2511      */                                                                                                  
2512     public void onClickSearchButton(View v) {                                                            
2513         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2514                                                                                                          
2515         onSearchRequested();                                                                             
2516     }                                                                                                    
2517                                                                                                          
2518     /**                                                                                                  
2519      * Event handler for the voice button                                                                
2520      *                                                                                                   
2521      * @param v The view that was clicked.                                                               
2522      */                                                                                                  
2523     public void onClickVoiceButton(View v) {                                                             
2524         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2525                                                                                                          
2526         startVoice();                                                                                    
2527     }                                                                                                    
2528                                                                                                          
2529     public void startVoice() {                                                                           
2530         try {                                                                                            
2531             final SearchManager searchManager =                                                          
2532                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);                            
2533             ComponentName activityName = searchManager.getGlobalSearchActivity();                        
2534             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2535             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2536             if (activityName != null) {                                                                  
2537                 intent.setPackage(activityName.getPackageName());                                        
2538             }                                                                                            
2539             startActivity(null, intent, "onClickVoiceButton");                                           
2540         } catch (ActivityNotFoundException e) {                                                          
2541             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2542             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2543             startActivitySafely(null, intent, "onClickVoiceButton");                                     
2544         }                                                                                                
2545     }                                                                                                    
2546                                                                                                          
2547     /**                                                                                                  
2548      * Event handler for the "grid" button that appears on the home screen, which                        
2549      * enters all apps mode.                                                                             
2550      *                                                                                                   
2551      * @param v The view that was clicked.                                                               
2552      */                                                                                                  
2553     protected void onClickAllAppsButton(View v) {                                                        
2554         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2555         if (isAllAppsVisible()) {                                                                        
2556             showWorkspace(true);                                                                         
2557         } else {                                                                                         
2558             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                   
2559         }                                                                                                
2560     }                                                                                                    
2561                                                                                                          
2562     private void showBrokenAppInstallDialog(final String packageName,                                    
2563             DialogInterface.OnClickListener onSearchClickListener) {                                     
2564         new AlertDialog.Builder(this)                                                                    
2565             .setTitle(R.string.abandoned_promises_title)                                                 
2566             .setMessage(R.string.abandoned_promise_explanation)                                          
2567             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2568             .setNeutralButton(R.string.abandoned_clean_this,                                             
2569                 new DialogInterface.OnClickListener() {                                                  
2570                     public void onClick(DialogInterface dialog, int id) {                                
2571                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2572                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2573                     }                                                                                    
2574                 })                                                                                       
2575             .create().show();                                                                            
2576         return;                                                                                          
2577     }                                                                                                    
2578                                                                                                          
2579     /**                                                                                                  
2580      * Event handler for an app shortcut click.                                                          
2581      *                                                                                                   
2582      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2583      */                                                                                                  
2584     protected void onClickAppShortcut(final View v) {                                                    
2585         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2586         Object tag = v.getTag();                                                                         
2587         if (!(tag instanceof ShortcutInfo)) {                                                            
2588             throw new IllegalArgumentException("Input must be a Shortcut");                              
2589         }                                                                                                
2590                                                                                                          
2591         // Open shortcut                                                                                 
2592         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2593                                                                                                          
2594         if (shortcut.isDisabled != 0) {                                                                  
2595             int error = R.string.activity_not_available;                                                 
2596             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2597                 error = R.string.safemode_shortcut_error;                                                
2598             }                                                                                            
2599             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2600             return;                                                                                      
2601         }                                                                                                
2602                                                                                                          
2603         final Intent intent = shortcut.intent;                                                           
2604                                                                                                          
2605         // Check for special shortcuts                                                                   
2606         if (intent.getComponent() != null) {                                                             
2607             final String shortcutClass = intent.getComponent().getClassName();                           
2608                                                                                                          
2609             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2610                 MemoryDumpActivity.startDump(this);                                                      
2611                 return;                                                                                  
2612             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2613                 toggleShowWeightWatcher();                                                               
2614                 return;                                                                                  
2615             }                                                                                            
2616         }                                                                                                
2617                                                                                                          
2618         // Check for abandoned promise                                                                   
2619         if ((v instanceof BubbleTextView)                                                                
2620                 && shortcut.isPromise()                                                                  
2621                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2622             showBrokenAppInstallDialog(                                                                  
2623                     shortcut.getTargetComponent().getPackageName(),                                      
2624                     new DialogInterface.OnClickListener() {                                              
2625                         public void onClick(DialogInterface dialog, int id) {                            
2626                             startAppShortcutOrInfoActivity(v);                                           
2627                         }                                                                                
2628                     });                                                                                  
2629             return;                                                                                      
2630         }                                                                                                
2631                                                                                                          
2632         // Start activities                                                                              
2633         startAppShortcutOrInfoActivity(v);                                                               
2634     }                                                                                                    
2635                                                                                                          
2636     private void startAppShortcutOrInfoActivity(View v) {                                                
2637         Object tag = v.getTag();                                                                         
2638         final ShortcutInfo shortcut;                                                                     
2639         final Intent intent;                                                                             
2640         if (tag instanceof ShortcutInfo) {                                                               
2641             shortcut = (ShortcutInfo) tag;                                                               
2642             intent = shortcut.intent;                                                                    
2643             int[] pos = new int[2];                                                                      
2644             v.getLocationOnScreen(pos);                                                                  
2645             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2646                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2647                                                                                                          
2648         } else if (tag instanceof AppInfo) {                                                             
2649             shortcut = null;                                                                             
2650             intent = ((AppInfo) tag).intent;                                                             
2651         } else {                                                                                         
2652             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2653         }                                                                                                
2654                                                                                                          
2655         boolean success = startActivitySafely(v, intent, tag);                                           
2656         mStats.recordLaunch(intent, shortcut);                                                           
2657                                                                                                          
2658         if (success && v instanceof BubbleTextView) {                                                    
2659             mWaitingForResume = (BubbleTextView) v;                                                      
2660             mWaitingForResume.setStayPressed(true);                                                      
2661         }                                                                                                
2662     }                                                                                                    
2663                                                                                                          
2664     /**                                                                                                  
2665      * Event handler for a folder icon click.                                                            
2666      *                                                                                                   
2667      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2668      */                                                                                                  
2669     protected void onClickFolderIcon(View v) {                                                           
2670         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2671         if (!(v instanceof FolderIcon)){                                                                 
2672             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2673         }                                                                                                
2674                                                                                                          
2675         FolderIcon folderIcon = (FolderIcon) v;                                                          
2676         final FolderInfo info = folderIcon.getFolderInfo();                                              
2677         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2678                                                                                                          
2679         // If the folder info reports that the associated folder is open, then verify that               
2680         // it is actually opened. There have been a few instances where this gets out of sync.           
2681         if (info.opened && openFolder == null) {                                                         
2682             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2683                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2684             info.opened = false;                                                                         
2685         }                                                                                                
2686                                                                                                          
2687         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2688             // Close any open folder                                                                     
2689             closeFolder();                                                                               
2690             // Open the requested folder                                                                 
2691             openFolder(folderIcon);                                                                      
2692         } else {                                                                                         
2693             // Find the open folder...                                                                   
2694             int folderScreen;                                                                            
2695             if (openFolder != null) {                                                                    
2696                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2697                 // .. and close it                                                                       
2698                 closeFolder(openFolder);                                                                 
2699                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2700                     // Close any folder open on the current screen                                       
2701                     closeFolder();                                                                       
2702                     // Pull the folder onto this screen                                                  
2703                     openFolder(folderIcon);                                                              
2704                 }                                                                                        
2705             }                                                                                            
2706         }                                                                                                
2707     }                                                                                                    
2708                                                                                                          
2709     /**                                                                                                  
2710      * Event handler for the (Add) Widgets button that appears after a long press                        
2711      * on the home screen.                                                                               
2712      */                                                                                                  
2713     protected void onClickAddWidgetButton(View view) {                                                   
2714         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2715         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                             
2716     }                                                                                                    
2717                                                                                                          
2718     /**                                                                                                  
2719      * Event handler for the wallpaper picker button that appears after a long press                     
2720      * on the home screen.                                                                               
2721      */                                                                                                  
2722     protected void onClickWallpaperPicker(View v) {                                                      
2723         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2724         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2725         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2726         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2727     }                                                                                                    
2728                                                                                                          
2729     /**                                                                                                  
2730      * Event handler for a click on the settings button that appears after a long press                  
2731      * on the home screen.                                                                               
2732      */                                                                                                  
2733     protected void onClickSettingsButton(View v) {                                                       
2734         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2735     }                                                                                                    
2736                                                                                                          
2737     public void onTouchDownAllAppsButton(View v) {                                                       
2738         // Provide the same haptic feedback that the system offers for virtual keys.                     
2739         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2740     }                                                                                                    
2741                                                                                                          
2742     public void performHapticFeedbackOnTouchDown(View v) {                                               
2743         // Provide the same haptic feedback that the system offers for virtual keys.                     
2744         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2745     }                                                                                                    
2746                                                                                                          
2747     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2748         if (mHapticFeedbackTouchListener == null) {                                                      
2749             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2750                 @Override                                                                                
2751                 public boolean onTouch(View v, MotionEvent event) {                                      
2752                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2753                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2754                     }                                                                                    
2755                     return false;                                                                        
2756                 }                                                                                        
2757             };                                                                                           
2758         }                                                                                                
2759         return mHapticFeedbackTouchListener;                                                             
2760     }                                                                                                    
2761                                                                                                          
2762     public void onDragStarted(View view) {}                                                              
2763                                                                                                          
2764     /**                                                                                                  
2765      * Called when the user stops interacting with the launcher.                                         
2766      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2767      */                                                                                                  
2768     protected void onInteractionEnd() {}                                                                 
2769                                                                                                          
2770     /**                                                                                                  
2771      * Called when the user starts interacting with the launcher.                                        
2772      * The possible interactions are:                                                                    
2773      *  - open all apps                                                                                  
2774      *  - reorder an app shortcut, or a widget                                                           
2775      *  - open the overview mode.                                                                        
2776      * This is a good time to stop doing things that only make sense                                     
2777      * when the user is on the homescreen and not doing housekeeping.                                    
2778      */                                                                                                  
2779     protected void onInteractionBegin() {}                                                               
2780                                                                                                          
2781     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2782         String packageName = componentName.getPackageName();                                             
2783         try {                                                                                            
2784             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2785             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2786             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2787         } catch (SecurityException e) {                                                                  
2788             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2789             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2790         } catch (ActivityNotFoundException e) {                                                          
2791             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2792             Log.e(TAG, "Unable to launch settings");                                                     
2793         }                                                                                                
2794     }                                                                                                    
2795                                                                                                          
2796     // returns true if the activity was started                                                          
2797     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2798             UserHandleCompat user) {                                                                     
2799         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2800             // System applications cannot be installed. For now, show a toast explaining that.           
2801             // We may give them the option of disabling apps this way.                                   
2802             int messageId = R.string.uninstall_system_app_text;                                          
2803             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2804             return false;                                                                                
2805         } else {                                                                                         
2806             String packageName = componentName.getPackageName();                                         
2807             String className = componentName.getClassName();                                             
2808             Intent intent = new Intent(                                                                  
2809                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2810             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2811                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2812             if (user != null) {                                                                          
2813                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2814             }                                                                                            
2815             startActivity(intent);                                                                       
2816             return true;                                                                                 
2817         }                                                                                                
2818     }                                                                                                    
2819                                                                                                          
2820     boolean startActivity(View v, Intent intent, Object tag) {                                           
2821         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2822         try {                                                                                            
2823             // Only launch using the new animation if the shortcut has not opted out (this is a          
2824             // private contract between launcher and may be ignored in the future).                      
2825             boolean useLaunchAnimation = (v != null) &&                                                  
2826                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2827             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2828             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2829                                                                                                          
2830             UserHandleCompat user = null;                                                                
2831             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2832                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2833                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2834             }                                                                                            
2835                                                                                                          
2836             Bundle optsBundle = null;                                                                    
2837             if (useLaunchAnimation) {                                                                    
2838                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2839                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2840                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2841                 optsBundle = opts.toBundle();                                                            
2842             }                                                                                            
2843                                                                                                          
2844             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2845                 // Could be launching some bookkeeping activity                                          
2846                 startActivity(intent, optsBundle);                                                       
2847             } else {                                                                                     
2848                 // TODO Component can be null when shortcuts are supported for secondary user            
2849                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2850                         intent.getSourceBounds(), optsBundle);                                           
2851             }                                                                                            
2852             return true;                                                                                 
2853         } catch (SecurityException e) {                                                                  
2854             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2855             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2856                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2857                     "or use the exported attribute for this activity. "                                  
2858                     + "tag="+ tag + " intent=" + intent, e);                                             
2859         }                                                                                                
2860         return false;                                                                                    
2861     }                                                                                                    
2862                                                                                                          
2863     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2864         boolean success = false;                                                                         
2865         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2866             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2867             return false;                                                                                
2868         }                                                                                                
2869         try {                                                                                            
2870             success = startActivity(v, intent, tag);                                                     
2871         } catch (ActivityNotFoundException e) {                                                          
2872             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2873             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2874         }                                                                                                
2875         return success;                                                                                  
2876     }                                                                                                    
2877                                                                                                          
2878     /**                                                                                                  
2879      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2880      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2881      */                                                                                                  
2882     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2883         final int width = fi.getMeasuredWidth();                                                         
2884         final int height = fi.getMeasuredHeight();                                                       
2885                                                                                                          
2886         // Lazy load ImageView, Bitmap and Canvas                                                        
2887         if (mFolderIconImageView == null) {                                                              
2888             mFolderIconImageView = new ImageView(this);                                                  
2889         }                                                                                                
2890         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2891                 mFolderIconBitmap.getHeight() != height) {                                               
2892             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2893             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2894         }                                                                                                
2895                                                                                                          
2896         DragLayer.LayoutParams lp;                                                                       
2897         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2898             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2899         } else {                                                                                         
2900             lp = new DragLayer.LayoutParams(width, height);                                              
2901         }                                                                                                
2902                                                                                                          
2903         // The layout from which the folder is being opened may be scaled, adjust the starting           
2904         // view size by this scale factor.                                                               
2905         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2906         lp.customPosition = true;                                                                        
2907         lp.x = mRectForFolderAnimation.left;                                                             
2908         lp.y = mRectForFolderAnimation.top;                                                              
2909         lp.width = (int) (scale * width);                                                                
2910         lp.height = (int) (scale * height);                                                              
2911                                                                                                          
2912         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
2913         fi.draw(mFolderIconCanvas);                                                                      
2914         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
2915         if (fi.getFolder() != null) {                                                                    
2916             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
2917             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
2918         }                                                                                                
2919         // Just in case this image view is still in the drag layer from a previous animation,            
2920         // we remove it and re-add it.                                                                   
2921         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
2922             mDragLayer.removeView(mFolderIconImageView);                                                 
2923         }                                                                                                
2924         mDragLayer.addView(mFolderIconImageView, lp);                                                    
2925         if (fi.getFolder() != null) {                                                                    
2926             fi.getFolder().bringToFront();                                                               
2927         }                                                                                                
2928     }                                                                                                    
2929                                                                                                          
2930     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
2931         if (fi == null) return;                                                                          
2932         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
2933         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
2934         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
2935                                                                                                          
2936         FolderInfo info = (FolderInfo) fi.getTag();                                                      
2937         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
2938             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
2939             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
2940             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
2941         }                                                                                                
2942                                                                                                          
2943         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
2944         copyFolderIconToImage(fi);                                                                       
2945         fi.setVisibility(View.INVISIBLE);                                                                
2946                                                                                                          
2947         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
2948                 scaleX, scaleY);                                                                         
2949         if (Utilities.isLmpOrAbove()) {                                                                  
2950             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
2951         }                                                                                                
2952         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2953         oa.start();                                                                                      
2954     }                                                                                                    
2955                                                                                                          
2956     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
2957         if (fi == null) return;                                                                          
2958         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
2959         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
2960         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
2961                                                                                                          
2962         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
2963                                                                                                          
2964         // We remove and re-draw the FolderIcon in-case it has changed                                   
2965         mDragLayer.removeView(mFolderIconImageView);                                                     
2966         copyFolderIconToImage(fi);                                                                       
2967         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
2968                 scaleX, scaleY);                                                                         
2969         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2970         oa.addListener(new AnimatorListenerAdapter() {                                                   
2971             @Override                                                                                    
2972             public void onAnimationEnd(Animator animation) {                                             
2973                 if (cl != null) {                                                                        
2974                     cl.clearFolderLeaveBehind();                                                         
2975                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
2976                     mDragLayer.removeView(mFolderIconImageView);                                         
2977                     fi.setVisibility(View.VISIBLE);                                                      
2978                 }                                                                                        
2979             }                                                                                            
2980         });                                                                                              
2981         oa.start();                                                                                      
2982     }                                                                                                    
2983                                                                                                          
2984     /**                                                                                                  
2985      * Opens the user folder described by the specified tag. The opening of the folder                   
2986      * is animated relative to the specified View. If the View is null, no animation                     
2987      * is played.                                                                                        
2988      *                                                                                                   
2989      * @param folderInfo The FolderInfo describing the folder to open.                                   
2990      */                                                                                                  
2991     public void openFolder(FolderIcon folderIcon) {                                                      
2992         Folder folder = folderIcon.getFolder();                                                          
2993         FolderInfo info = folder.mInfo;                                                                  
2994                                                                                                          
2995         info.opened = true;                                                                              
2996                                                                                                          
2997         // Just verify that the folder hasn't already been added to the DragLayer.                       
2998         // There was a one-off crash where the folder had a parent already.                              
2999         if (folder.getParent() == null) {                                                                
3000             mDragLayer.addView(folder);                                                                  
3001             mDragController.addDropTarget((DropTarget) folder);                                          
3002         } else {                                                                                         
3003             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3004                     folder.getParent() + ").");                                                          
3005         }                                                                                                
3006         folder.animateOpen();                                                                            
3007         growAndFadeOutFolderIcon(folderIcon);                                                            
3008                                                                                                          
3009         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3010         // the workspace items                                                                           
3011         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3012         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3013     }                                                                                                    
3014                                                                                                          
3015     public void closeFolder() {                                                                          
3016         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3017         if (folder != null) {                                                                            
3018             if (folder.isEditingName()) {                                                                
3019                 folder.dismissEditingName();                                                             
3020             }                                                                                            
3021             closeFolder(folder);                                                                         
3022         }                                                                                                
3023     }                                                                                                    
3024                                                                                                          
3025     void closeFolder(Folder folder) {                                                                    
3026         folder.getInfo().opened = false;                                                                 
3027                                                                                                          
3028         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3029         if (parent != null) {                                                                            
3030             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3031             shrinkAndFadeInFolderIcon(fi);                                                               
3032         }                                                                                                
3033         folder.animateClosed();                                                                          
3034                                                                                                          
3035         // Notify the accessibility manager that this folder "window" has disappeard and no              
3036         // longer occludeds the workspace items                                                          
3037         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3038     }                                                                                                    
3039                                                                                                          
3040     public boolean onLongClick(View v) {                                                                 
3041         if (!isDraggingEnabled()) return false;                                                          
3042         if (isWorkspaceLocked()) return false;                                                           
3043         if (mState != State.WORKSPACE) return false;                                                     
3044                                                                                                          
3045         if (v instanceof Workspace) {                                                                    
3046             if (!mWorkspace.isInOverviewMode()) {                                                        
3047                 if (mWorkspace.enterOverviewMode()) {                                                    
3048                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3049                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3050                     return true;                                                                         
3051                 } else {                                                                                 
3052                     return false;                                                                        
3053                 }                                                                                        
3054             } else {                                                                                     
3055                 return false;                                                                            
3056             }                                                                                            
3057         }                                                                                                
3058                                                                                                          
3059         CellLayout.CellInfo longClickCellInfo = null;                                                    
3060         View itemUnderLongClick = null;                                                                  
3061         if (v.getTag() instanceof ItemInfo) {                                                            
3062             ItemInfo info = (ItemInfo) v.getTag();                                                       
3063             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3064             itemUnderLongClick = longClickCellInfo.cell;                                                 
3065             resetAddInfo();                                                                              
3066         }                                                                                                
3067                                                                                                          
3068         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3069         // on hotseat items.                                                                             
3070         final boolean inHotseat = isHotseatLayout(v);                                                    
3071         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3072         if (allowLongPress && !mDragController.isDragging()) {                                           
3073             if (itemUnderLongClick == null) {                                                            
3074                 // User long pressed on empty space                                                      
3075                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3076                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3077                 if (mWorkspace.isInOverviewMode()) {                                                     
3078                     mWorkspace.startReordering(v);                                                       
3079                 } else {                                                                                 
3080                     mWorkspace.enterOverviewMode();                                                      
3081                 }                                                                                        
3082             } else {                                                                                     
3083                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3084                         mHotseat.getOrderInHotseat(                                                      
3085                                 longClickCellInfo.cellX,                                                 
3086                                 longClickCellInfo.cellY));                                               
3087                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3088                     // User long pressed on an item                                                      
3089                     mWorkspace.startDrag(longClickCellInfo);                                             
3090                 }                                                                                        
3091             }                                                                                            
3092         }                                                                                                
3093         return true;                                                                                     
3094     }                                                                                                    
3095                                                                                                          
3096     boolean isHotseatLayout(View layout) {                                                               
3097         return mHotseat != null && layout != null &&                                                     
3098                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3099     }                                                                                                    
3100                                                                                                          
3101     /**                                                                                                  
3102      * Returns the CellLayout of the specified container at the specified screen.                        
3103      */                                                                                                  
3104     CellLayout getCellLayout(long container, long screenId) {                                            
3105         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3106             if (mHotseat != null) {                                                                      
3107                 return mHotseat.getLayout();                                                             
3108             } else {                                                                                     
3109                 return null;                                                                             
3110             }                                                                                            
3111         } else {                                                                                         
3112             return (CellLayout) mWorkspace.getScreenWithId(screenId);                                    
3113         }                                                                                                
3114     }                                                                                                    
3115                                                                                                          
3116     public boolean isAllAppsVisible() {                                                                  
3117         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);             
3118     }                                                                                                    
3119                                                                                                          
3120     private void setWorkspaceBackground(boolean workspace) {                                             
3121         mLauncherView.setBackground(workspace ?                                                          
3122                 mWorkspaceBackgroundDrawable : null);                                                    
3123     }                                                                                                    
3124                                                                                                          
3125     protected void changeWallpaperVisiblity(boolean visible) {                                           
3126         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3127         int curflags = getWindow().getAttributes().flags                                                 
3128                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3129         if (wpflags != curflags) {                                                                       
3130             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3131         }                                                                                                
3132         setWorkspaceBackground(visible);                                                                 
3133     }                                                                                                    
3134                                                                                                          
3135     private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {    
3136         if (v instanceof LauncherTransitionable) {                                                       
3137             ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);       
3138         }                                                                                                
3139     }                                                                                                    
3140                                                                                                          
3141     private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {      
3142         if (v instanceof LauncherTransitionable) {                                                       
3143             ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);         
3144         }                                                                                                
3145                                                                                                          
3146         // Update the workspace transition step as well                                                  
3147         dispatchOnLauncherTransitionStep(v, 0f);                                                         
3148     }                                                                                                    
3149                                                                                                          
3150     private void dispatchOnLauncherTransitionStep(View v, float t) {                                     
3151         if (v instanceof LauncherTransitionable) {                                                       
3152             ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                              
3153         }                                                                                                
3154     }                                                                                                    
3155                                                                                                          
3156     private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {        
3157         if (v instanceof LauncherTransitionable) {                                                       
3158             ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);           
3159         }                                                                                                
3160                                                                                                          
3161         // Update the workspace transition step as well                                                  
3162         dispatchOnLauncherTransitionStep(v, 1f);                                                         
3163     }                                                                                                    
3164                                                                                                          
3165     /**                                                                                                  
3166      * Things to test when changing the following seven functions.                                       
3167      *   - Home from workspace                                                                           
3168      *          - from center screen                                                                     
3169      *          - from other screens                                                                     
3170      *   - Home from all apps                                                                            
3171      *          - from center screen                                                                     
3172      *          - from other screens                                                                     
3173      *   - Back from all apps                                                                            
3174      *          - from center screen                                                                     
3175      *          - from other screens                                                                     
3176      *   - Launch app from workspace and quit                                                            
3177      *          - with back                                                                              
3178      *          - with home                                                                              
3179      *   - Launch app from all apps and quit                                                             
3180      *          - with back                                                                              
3181      *          - with home                                                                              
3182      *   - Go to a screen that's not the default, then all                                               
3183      *     apps, and launch and app, and go back                                                         
3184      *          - with back                                                                              
3185      *          -with home                                                                               
3186      *   - On workspace, long press power and go back                                                    
3187      *          - with back                                                                              
3188      *          - with home                                                                              
3189      *   - On all apps, long press power and go back                                                     
3190      *          - with back                                                                              
3191      *          - with home                                                                              
3192      *   - On workspace, power off                                                                       
3193      *   - On all apps, power off                                                                        
3194      *   - Launch an app and turn off the screen while in that app                                       
3195      *          - Go back with home key                                                                  
3196      *          - Go back with back key  TODO: make this not go to workspace                             
3197      *          - From all apps                                                                          
3198      *          - From workspace                                                                         
3199      *   - Enter and exit car mode (becuase it causes an extra configuration changed)                    
3200      *          - From all apps                                                                          
3201      *          - From the center workspace                                                              
3202      *          - From another workspace                                                                 
3203      */                                                                                                  
3204                                                                                                          
3205     /**                                                                                                  
3206      * Zoom the camera out from the workspace to reveal 'toView'.                                        
3207      * Assumes that the view to show is anchored at either the very top or very bottom                   
3208      * of the screen.                                                                                    
3209      */                                                                                                  
3210     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {           
3211         AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();         
3212         showAppsCustomizeHelper(animated, springLoaded, contentType);                                    
3213     }                                                                                                    
3214                                                                                                          
3215     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,             
3216                                          final AppsCustomizePagedView.ContentType contentType) {         
3217         if (mStateAnimation != null) {                                                                   
3218             mStateAnimation.setDuration(0);                                                              
3219             mStateAnimation.cancel();                                                                    
3220             mStateAnimation = null;                                                                      
3221         }                                                                                                
3222                                                                                                          
3223         boolean material = Utilities.isLmpOrAbove();                                                     
3224                                                                                                          
3225         final Resources res = getResources();                                                            
3226                                                                                                          
3227         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                   
3228         final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);               
3229         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);             
3230         final int itemsAlphaStagger =                                                                    
3231                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3232                                                                                                          
3233         final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);       
3234         final View fromView = mWorkspace;                                                                
3235         final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                       
3236                                                                                                          
3237         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3238                                                                                                          
3239         Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?     
3240                 Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                         
3241         Animator workspaceAnim =                                                                         
3242                 mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                
3243         if (!LauncherAppState.isDisableAllApps()                                                         
3244                 || contentType == AppsCustomizePagedView.ContentType.Widgets) {                          
3245             // Set the content type for the all apps/widgets space                                       
3246             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                  
3247         }                                                                                                
3248                                                                                                          
3249         // If for some reason our views aren't initialized, don't animate                                
3250         boolean initialized = getAllAppsButton() != null;                                                
3251                                                                                                          
3252         if (animated && initialized) {                                                                   
3253             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3254             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3255                     toView.findViewById(R.id.apps_customize_pane_content);                               
3256                                                                                                          
3257             final View page = content.getPageAt(content.getCurrentPage());                               
3258             final View revealView = toView.findViewById(R.id.fake_page);                                 
3259                                                                                                          
3260             final float initialPanelAlpha = 1f;                                                          
3261                                                                                                          
3262             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;      
3263             if (isWidgetTray) {                                                                          
3264                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                
3265             } else {                                                                                     
3266                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                     
3267             }                                                                                            
3268                                                                                                          
3269             // Hide the real page background, and swap in the fake one                                   
3270             content.setPageBackgroundsVisible(false);                                                    
3271             revealView.setVisibility(View.VISIBLE);                                                      
3272             // We need to hide this view as the animation start will be posted.                          
3273             revealView.setAlpha(0);                                                                      
3274                                                                                                          
3275             int width = revealView.getMeasuredWidth();                                                   
3276             int height = revealView.getMeasuredHeight();                                                 
3277             float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);         
3278                                                                                                          
3279             revealView.setTranslationY(0);                                                               
3280             revealView.setTranslationX(0);                                                               
3281                                                                                                          
3282             // Get the y delta between the center of the page and the center of the all apps button      
3283             int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                
3284                     getAllAppsButton(), null);                                                           
3285                                                                                                          
3286             float alpha = 0;                                                                             
3287             float xDrift = 0;                                                                            
3288             float yDrift = 0;                                                                            
3289             if (material) {                                                                              
3290                 alpha = isWidgetTray ? 0.3f : 1f;                                                        
3291                 yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                             
3292                 xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                      
3293             } else {                                                                                     
3294                 yDrift = 2 * height / 3;                                                                 
3295                 xDrift = 0;                                                                              
3296             }                                                                                            
3297             final float initAlpha = alpha;                                                               
3298                                                                                                          
3299             revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                     
3300             layerViews.add(revealView);                                                                  
3301             PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);      
3302             PropertyValuesHolder panelDriftY =                                                           
3303                     PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                             
3304             PropertyValuesHolder panelDriftX =                                                           
3305                     PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                             
3306                                                                                                          
3307             ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,        
3308                     panelAlpha, panelDriftY, panelDriftX);                                               
3309                                                                                                          
3310             panelAlphaAndDrift.setDuration(revealDuration);                                              
3311             panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                   
3312                                                                                                          
3313             mStateAnimation.play(panelAlphaAndDrift);                                                    
3314                                                                                                          
3315             if (page != null) {                                                                          
3316                 page.setVisibility(View.VISIBLE);                                                        
3317                 page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3318                 layerViews.add(page);                                                                    
3319                                                                                                          
3320                 ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);      
3321                 page.setTranslationY(yDrift);                                                            
3322                 pageDrift.setDuration(revealDuration);                                                   
3323                 pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                        
3324                 pageDrift.setStartDelay(itemsAlphaStagger);                                              
3325                 mStateAnimation.play(pageDrift);                                                         
3326                                                                                                          
3327                 page.setAlpha(0f);                                                                       
3328                 ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);               
3329                 itemsAlpha.setDuration(revealDuration);                                                  
3330                 itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                            
3331                 itemsAlpha.setStartDelay(itemsAlphaStagger);                                             
3332                 mStateAnimation.play(itemsAlpha);                                                        
3333             }                                                                                            
3334                                                                                                          
3335             View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);               
3336             pageIndicators.setAlpha(0.01f);                                                              
3337             ObjectAnimator indicatorsAlpha =                                                             
3338                     ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                 
3339             indicatorsAlpha.setDuration(revealDuration);                                                 
3340             mStateAnimation.play(indicatorsAlpha);                                                       
3341                                                                                                          
3342             if (material) {                                                                              
3343                 final View allApps = getAllAppsButton();                                                 
3344                 int allAppsButtonSize = LauncherAppState.getInstance().                                  
3345                         getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                     
3346                 float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                            
3347                 Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,         
3348                                 height / 2, startRadius, revealRadius);                                  
3349                 reveal.setDuration(revealDuration);                                                      
3350                 reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                           
3351                                                                                                          
3352                 reveal.addListener(new AnimatorListenerAdapter() {                                       
3353                     public void onAnimationStart(Animator animation) {                                   
3354                         if (!isWidgetTray) {                                                             
3355                             allApps.setVisibility(View.INVISIBLE);                                       
3356                         }                                                                                
3357                     }                                                                                    
3358                     public void onAnimationEnd(Animator animation) {                                     
3359                         if (!isWidgetTray) {                                                             
3360                             allApps.setVisibility(View.VISIBLE);                                         
3361                         }                                                                                
3362                     }                                                                                    
3363                 });                                                                                      
3364                 mStateAnimation.play(reveal);                                                            
3365             }                                                                                            
3366                                                                                                          
3367             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3368                 @Override                                                                                
3369                 public void onAnimationEnd(Animator animation) {                                         
3370                     dispatchOnLauncherTransitionEnd(fromView, animated, false);                          
3371                     dispatchOnLauncherTransitionEnd(toView, animated, false);                            
3372                                                                                                          
3373                     revealView.setVisibility(View.INVISIBLE);                                            
3374                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3375                     if (page != null) {                                                                  
3376                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3377                     }                                                                                    
3378                     content.setPageBackgroundsVisible(true);                                             
3379                                                                                                          
3380                     // Hide the search bar                                                               
3381                     if (mSearchDropTargetBar != null) {                                                  
3382                         mSearchDropTargetBar.hideSearchBar(false);                                       
3383                     }                                                                                    
3384                 }                                                                                        
3385                                                                                                          
3386             });                                                                                          
3387                                                                                                          
3388             if (workspaceAnim != null) {                                                                 
3389                 mStateAnimation.play(workspaceAnim);                                                     
3390             }                                                                                            
3391                                                                                                          
3392             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3393             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3394             final AnimatorSet stateAnimation = mStateAnimation;                                          
3395             final Runnable startAnimRunnable = new Runnable() {                                          
3396                 public void run() {                                                                      
3397                     // Check that mStateAnimation hasn't changed while                                   
3398                     // we waited for a layout/draw pass                                                  
3399                     if (mStateAnimation != stateAnimation)                                               
3400                         return;                                                                          
3401                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3402                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3403                                                                                                          
3404                     revealView.setAlpha(initAlpha);                                                      
3405                     if (Utilities.isLmpOrAbove()) {                                                      
3406                         for (int i = 0; i < layerViews.size(); i++) {                                    
3407                             View v = layerViews.get(i);                                                  
3408                             if (v != null) {                                                             
3409                                 boolean attached = true;                                                 
3410                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3411                                     attached = v.isAttachedToWindow();                                   
3412                                 }                                                                        
3413                                 if (attached) v.buildLayer();                                            
3414                             }                                                                            
3415                         }                                                                                
3416                     }                                                                                    
3417                     mStateAnimation.start();                                                             
3418                 }                                                                                        
3419             };                                                                                           
3420             toView.bringToFront();                                                                       
3421             toView.setVisibility(View.VISIBLE);                                                          
3422             toView.post(startAnimRunnable);                                                              
3423         } else {                                                                                         
3424             toView.setTranslationX(0.0f);                                                                
3425             toView.setTranslationY(0.0f);                                                                
3426             toView.setScaleX(1.0f);                                                                      
3427             toView.setScaleY(1.0f);                                                                      
3428             toView.setVisibility(View.VISIBLE);                                                          
3429             toView.bringToFront();                                                                       
3430                                                                                                          
3431             if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                      
3432                 // Hide the search bar                                                                   
3433                 if (mSearchDropTargetBar != null) {                                                      
3434                     mSearchDropTargetBar.hideSearchBar(false);                                           
3435                 }                                                                                        
3436             }                                                                                            
3437             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3438             dispatchOnLauncherTransitionStart(fromView, animated, false);                                
3439             dispatchOnLauncherTransitionEnd(fromView, animated, false);                                  
3440             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3441             dispatchOnLauncherTransitionStart(toView, animated, false);                                  
3442             dispatchOnLauncherTransitionEnd(toView, animated, false);                                    
3443         }                                                                                                
3444     }                                                                                                    
3445                                                                                                          
3446     /**                                                                                                  
3447      * Zoom the camera back into the workspace, hiding 'fromView'.                                       
3448      * This is the opposite of showAppsCustomizeHelper.                                                  
3449      * @param animated If true, the transition will be animated.                                         
3450      */                                                                                                  
3451     private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                
3452             final boolean springLoaded, final Runnable onCompleteRunnable) {                             
3453                                                                                                          
3454         if (mStateAnimation != null) {                                                                   
3455             mStateAnimation.setDuration(0);                                                              
3456             mStateAnimation.cancel();                                                                    
3457             mStateAnimation = null;                                                                      
3458         }                                                                                                
3459                                                                                                          
3460         boolean material = Utilities.isLmpOrAbove();                                                     
3461         Resources res = getResources();                                                                  
3462                                                                                                          
3463         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                  
3464         final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);           
3465         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);            
3466         final int itemsAlphaStagger =                                                                    
3467                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3468                                                                                                          
3469         final float scaleFactor = (float)                                                                
3470                 res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                           
3471         final View fromView = mAppsCustomizeTabHost;                                                     
3472         final View toView = mWorkspace;                                                                  
3473         Animator workspaceAnim = null;                                                                   
3474         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3475                                                                                                          
3476         if (toState == Workspace.State.NORMAL) {                                                         
3477             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3478                     toState, animated, layerViews);                                                      
3479         } else if (toState == Workspace.State.SPRING_LOADED ||                                           
3480                 toState == Workspace.State.OVERVIEW) {                                                   
3481             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3482                     toState, animated, layerViews);                                                      
3483         }                                                                                                
3484                                                                                                          
3485         // If for some reason our views aren't initialized, don't animate                                
3486         boolean initialized = getAllAppsButton() != null;                                                
3487                                                                                                          
3488         if (animated && initialized) {                                                                   
3489             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3490             if (workspaceAnim != null) {                                                                 
3491                 mStateAnimation.play(workspaceAnim);                                                     
3492             }                                                                                            
3493                                                                                                          
3494             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3495                     fromView.findViewById(R.id.apps_customize_pane_content);                             
3496                                                                                                          
3497             final View page = content.getPageAt(content.getNextPage());                                  
3498                                                                                                          
3499             // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases        
3500             int count = content.getChildCount();                                                         
3501             for (int i = 0; i < count; i++) {                                                            
3502                 View child = content.getChildAt(i);                                                      
3503                 if (child != page) {                                                                     
3504                     child.setVisibility(View.INVISIBLE);                                                 
3505                 }                                                                                        
3506             }                                                                                            
3507             final View revealView = fromView.findViewById(R.id.fake_page);                               
3508                                                                                                          
3509             // hideAppsCustomizeHelper is called in some cases when it is already hidden                 
3510             // don't perform all these no-op animations. In particularly, this was causing               
3511             // the all-apps button to pop in and out.                                                    
3512             if (fromView.getVisibility() == View.VISIBLE) {                                              
3513                 AppsCustomizePagedView.ContentType contentType = content.getContentType();               
3514                 final boolean isWidgetTray =                                                             
3515                         contentType == AppsCustomizePagedView.ContentType.Widgets;                       
3516                                                                                                          
3517                 if (isWidgetTray) {                                                                      
3518                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));            
3519                 } else {                                                                                 
3520                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                 
3521                 }                                                                                        
3522                                                                                                          
3523                 int width = revealView.getMeasuredWidth();                                               
3524                 int height = revealView.getMeasuredHeight();                                             
3525                 float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);     
3526                                                                                                          
3527                 // Hide the real page background, and swap in the fake one                               
3528                 revealView.setVisibility(View.VISIBLE);                                                  
3529                 content.setPageBackgroundsVisible(false);                                                
3530                                                                                                          
3531                 final View allAppsButton = getAllAppsButton();                                           
3532                 revealView.setTranslationY(0);                                                           
3533                 int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,            
3534                         allAppsButton, null);                                                            
3535                                                                                                          
3536                 float xDrift = 0;                                                                        
3537                 float yDrift = 0;                                                                        
3538                 if (material) {                                                                          
3539                     yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                         
3540                     xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                  
3541                 } else {                                                                                 
3542                     yDrift = 5 * height / 4;                                                             
3543                     xDrift = 0;                                                                          
3544                 }                                                                                        
3545                                                                                                          
3546                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                 
3547                 TimeInterpolator decelerateInterpolator = material ?                                     
3548                         new LogDecelerateInterpolator(100, 0) :                                          
3549                         new LogDecelerateInterpolator(30, 0);                                            
3550                                                                                                          
3551                 // The vertical motion of the apps panel should be delayed by one frame                  
3552                 // from the conceal animation in order to give the right feel. We correpsondingly        
3553                 // shorten the duration so that the slide and conceal end at the same time.              
3554                 ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",       
3555                         0, yDrift);                                                                      
3556                 panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3557                 panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3558                 panelDriftY.setInterpolator(decelerateInterpolator);                                     
3559                 mStateAnimation.play(panelDriftY);                                                       
3560                                                                                                          
3561                 ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",       
3562                         0, xDrift);                                                                      
3563                 panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3564                 panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3565                 panelDriftX.setInterpolator(decelerateInterpolator);                                     
3566                 mStateAnimation.play(panelDriftX);                                                       
3567                                                                                                          
3568                 if (isWidgetTray || !material) {                                                         
3569                     float finalAlpha = material ? 0.4f : 0f;                                             
3570                     revealView.setAlpha(1f);                                                             
3571                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",           
3572                             1f, finalAlpha);                                                             
3573                     panelAlpha.setDuration(revealDuration);                                              
3574                     panelAlpha.setInterpolator(material ? decelerateInterpolator :                       
3575                         new AccelerateInterpolator(1.5f));                                               
3576                     mStateAnimation.play(panelAlpha);                                                    
3577                 }                                                                                        
3578                                                                                                          
3579                 if (page != null) {                                                                      
3580                     page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                   
3581                                                                                                          
3582                     ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",           
3583                             0, yDrift);                                                                  
3584                     page.setTranslationY(0);                                                             
3585                     pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                          
3586                     pageDrift.setInterpolator(decelerateInterpolator);                                   
3587                     pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                     
3588                     mStateAnimation.play(pageDrift);                                                     
3589                                                                                                          
3590                     page.setAlpha(1f);                                                                   
3591                     ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);        
3592                     itemsAlpha.setDuration(100);                                                         
3593                     itemsAlpha.setInterpolator(decelerateInterpolator);                                  
3594                     mStateAnimation.play(itemsAlpha);                                                    
3595                 }                                                                                        
3596                                                                                                          
3597                 View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);         
3598                 pageIndicators.setAlpha(1f);                                                             
3599                 ObjectAnimator indicatorsAlpha =                                                         
3600                         LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                          
3601                 indicatorsAlpha.setDuration(revealDuration);                                             
3602                 indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                       
3603                 mStateAnimation.play(indicatorsAlpha);                                                   
3604                                                                                                          
3605                 width = revealView.getMeasuredWidth();                                                   
3606                                                                                                          
3607                 if (material) {                                                                          
3608                     if (!isWidgetTray) {                                                                 
3609                         allAppsButton.setVisibility(View.INVISIBLE);                                     
3610                     }                                                                                    
3611                     int allAppsButtonSize = LauncherAppState.getInstance().                              
3612                             getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                 
3613                     float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                        
3614                     Animator reveal =                                                                    
3615                             LauncherAnimUtils.createCircularReveal(revealView, width / 2,                
3616                                     height / 2, revealRadius, finalRadius);                              
3617                     reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                       
3618                     reveal.setDuration(revealDuration);                                                  
3619                     reveal.setStartDelay(itemsAlphaStagger);                                             
3620                                                                                                          
3621                     reveal.addListener(new AnimatorListenerAdapter() {                                   
3622                         public void onAnimationEnd(Animator animation) {                                 
3623                             revealView.setVisibility(View.INVISIBLE);                                    
3624                             if (!isWidgetTray) {                                                         
3625                                 allAppsButton.setVisibility(View.VISIBLE);                               
3626                             }                                                                            
3627                         }                                                                                
3628                     });                                                                                  
3629                                                                                                          
3630                     mStateAnimation.play(reveal);                                                        
3631                 }                                                                                        
3632                                                                                                          
3633                 dispatchOnLauncherTransitionPrepare(fromView, animated, true);                           
3634                 dispatchOnLauncherTransitionPrepare(toView, animated, true);                             
3635                 mAppsCustomizeContent.stopScrolling();                                                   
3636             }                                                                                            
3637                                                                                                          
3638             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3639                 @Override                                                                                
3640                 public void onAnimationEnd(Animator animation) {                                         
3641                     fromView.setVisibility(View.GONE);                                                   
3642                     dispatchOnLauncherTransitionEnd(fromView, animated, true);                           
3643                     dispatchOnLauncherTransitionEnd(toView, animated, true);                             
3644                     if (onCompleteRunnable != null) {                                                    
3645                         onCompleteRunnable.run();                                                        
3646                     }                                                                                    
3647                                                                                                          
3648                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3649                     if (page != null) {                                                                  
3650                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3651                     }                                                                                    
3652                     content.setPageBackgroundsVisible(true);                                             
3653                     // Unhide side pages                                                                 
3654                     int count = content.getChildCount();                                                 
3655                     for (int i = 0; i < count; i++) {                                                    
3656                         View child = content.getChildAt(i);                                              
3657                         child.setVisibility(View.VISIBLE);                                               
3658                     }                                                                                    
3659                                                                                                          
3660                     // Reset page transforms                                                             
3661                     if (page != null) {                                                                  
3662                         page.setTranslationX(0);                                                         
3663                         page.setTranslationY(0);                                                         
3664                         page.setAlpha(1);                                                                
3665                     }                                                                                    
3666                     content.setCurrentPage(content.getNextPage());                                       
3667                                                                                                          
3668                     mAppsCustomizeContent.updateCurrentPageScroll();                                     
3669                 }                                                                                        
3670             });                                                                                          
3671                                                                                                          
3672             final AnimatorSet stateAnimation = mStateAnimation;                                          
3673             final Runnable startAnimRunnable = new Runnable() {                                          
3674                 public void run() {                                                                      
3675                     // Check that mStateAnimation hasn't changed while                                   
3676                     // we waited for a layout/draw pass                                                  
3677                     if (mStateAnimation != stateAnimation)                                               
3678                         return;                                                                          
3679                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3680                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3681                                                                                                          
3682                     if (Utilities.isLmpOrAbove()) {                                                      
3683                         for (int i = 0; i < layerViews.size(); i++) {                                    
3684                             View v = layerViews.get(i);                                                  
3685                             if (v != null) {                                                             
3686                                 boolean attached = true;                                                 
3687                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3688                                     attached = v.isAttachedToWindow();                                   
3689                                 }                                                                        
3690                                 if (attached) v.buildLayer();                                            
3691                             }                                                                            
3692                         }                                                                                
3693                     }                                                                                    
3694                     mStateAnimation.start();                                                             
3695                 }                                                                                        
3696             };                                                                                           
3697             fromView.post(startAnimRunnable);                                                            
3698         } else {                                                                                         
3699             fromView.setVisibility(View.GONE);                                                           
3700             dispatchOnLauncherTransitionPrepare(fromView, animated, true);                               
3701             dispatchOnLauncherTransitionStart(fromView, animated, true);                                 
3702             dispatchOnLauncherTransitionEnd(fromView, animated, true);                                   
3703             dispatchOnLauncherTransitionPrepare(toView, animated, true);                                 
3704             dispatchOnLauncherTransitionStart(toView, animated, true);                                   
3705             dispatchOnLauncherTransitionEnd(toView, animated, true);                                     
3706         }                                                                                                
3707     }                                                                                                    
3708                                                                                                          
3709     @Override                                                                                            
3710     public void onTrimMemory(int level) {                                                                
3711         super.onTrimMemory(level);                                                                       
3712         if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                         
3713             mAppsCustomizeTabHost.onTrimMemory();                                                        
3714         }                                                                                                
3715     }                                                                                                    
3716                                                                                                          
3717     protected void showWorkspace(boolean animated) {                                                     
3718         showWorkspace(animated, null);                                                                   
3719     }                                                                                                    
3720                                                                                                          
3721     protected void showWorkspace() {                                                                     
3722         showWorkspace(true);                                                                             
3723     }                                                                                                    
3724                                                                                                          
3725     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3726         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3727             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3728             mWorkspace.setVisibility(View.VISIBLE);                                                      
3729             hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);        
3730                                                                                                          
3731             // Show the search bar (only animate if we were showing the drop target bar in spring        
3732             // loaded mode)                                                                              
3733             if (mSearchDropTargetBar != null) {                                                          
3734                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3735             }                                                                                            
3736                                                                                                          
3737             // Set focus to the AppsCustomize button                                                     
3738             if (mAllAppsButton != null) {                                                                
3739                 mAllAppsButton.requestFocus();                                                           
3740             }                                                                                            
3741         }                                                                                                
3742                                                                                                          
3743         // Change the state *after* we've called all the transition code                                 
3744         mState = State.WORKSPACE;                                                                        
3745                                                                                                          
3746         // Resume the auto-advance of widgets                                                            
3747         mUserPresent = true;                                                                             
3748         updateRunning();                                                                                 
3749                                                                                                          
3750         // Send an accessibility event to announce the context change                                    
3751         getWindow().getDecorView()                                                                       
3752                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3753                                                                                                          
3754         onWorkspaceShown(animated);                                                                      
3755     }                                                                                                    
3756                                                                                                          
3757     void showOverviewMode(boolean animated) {                                                            
3758         mWorkspace.setVisibility(View.VISIBLE);                                                          
3759         hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                        
3760         mState = State.WORKSPACE;                                                                        
3761         onWorkspaceShown(animated);                                                                      
3762     }                                                                                                    
3763                                                                                                          
3764     public void onWorkspaceShown(boolean animated) {                                                     
3765     }                                                                                                    
3766                                                                                                          
3767     void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                   
3768                      boolean resetPageToZero) {                                                          
3769         if (mState != State.WORKSPACE) return;                                                           
3770                                                                                                          
3771         if (resetPageToZero) {                                                                           
3772             mAppsCustomizeTabHost.reset();                                                               
3773         }                                                                                                
3774         showAppsCustomizeHelper(animated, false, contentType);                                           
3775         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3776             @Override                                                                                    
3777             public void run() {                                                                          
3778                 // We post this in-case the all apps view isn't yet constructed.                         
3779                 mAppsCustomizeTabHost.requestFocus();                                                    
3780             }                                                                                            
3781         });                                                                                              
3782                                                                                                          
3783         // Change the state *after* we've called all the transition code                                 
3784         mState = State.APPS_CUSTOMIZE;                                                                   
3785                                                                                                          
3786         // Pause the auto-advance of widgets until we are out of AllApps                                 
3787         mUserPresent = false;                                                                            
3788         updateRunning();                                                                                 
3789         closeFolder();                                                                                   
3790                                                                                                          
3791         // Send an accessibility event to announce the context change                                    
3792         getWindow().getDecorView()                                                                       
3793                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3794     }                                                                                                    
3795                                                                                                          
3796     void enterSpringLoadedDragMode() {                                                                   
3797         if (isAllAppsVisible()) {                                                                        
3798             hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                    
3799             mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                 
3800         }                                                                                                
3801     }                                                                                                    
3802                                                                                                          
3803     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3804             final Runnable onCompleteRunnable) {                                                         
3805         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                        
3806                                                                                                          
3807         mHandler.postDelayed(new Runnable() {                                                            
3808             @Override                                                                                    
3809             public void run() {                                                                          
3810                 if (successfulDrop) {                                                                    
3811                     // Before we show workspace, hide all apps again because                             
3812                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3813                     // clean up our state transition functions                                           
3814                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3815                     showWorkspace(true, onCompleteRunnable);                                             
3816                 } else {                                                                                 
3817                     exitSpringLoadedDragMode();                                                          
3818                 }                                                                                        
3819             }                                                                                            
3820         }, delay);                                                                                       
3821     }                                                                                                    
3822                                                                                                          
3823     void exitSpringLoadedDragMode() {                                                                    
3824         if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3825             final boolean animated = true;                                                               
3826             final boolean springLoaded = true;                                                           
3827             showAppsCustomizeHelper(animated, springLoaded);                                             
3828             mState = State.APPS_CUSTOMIZE;                                                               
3829         }                                                                                                
3830         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3831     }                                                                                                    
3832                                                                                                          
3833     void lockAllApps() {                                                                                 
3834         // TODO                                                                                          
3835     }                                                                                                    
3836                                                                                                          
3837     void unlockAllApps() {                                                                               
3838         // TODO                                                                                          
3839     }                                                                                                    
3840                                                                                                          
3841     /**                                                                                                  
3842      * Hides the hotseat area.                                                                           
3843      */                                                                                                  
3844     void hideHotseat(boolean animated) {                                                                 
3845         if (!LauncherAppState.getInstance().isScreenLarge()) {                                           
3846             if (animated) {                                                                              
3847                 if (mHotseat.getAlpha() != 0f) {                                                         
3848                     int duration = 0;                                                                    
3849                     if (mSearchDropTargetBar != null) {                                                  
3850                         duration = mSearchDropTargetBar.getTransitionOutDuration();                      
3851                     }                                                                                    
3852                     mHotseat.animate().alpha(0f).setDuration(duration);                                  
3853                 }                                                                                        
3854             } else {                                                                                     
3855                 mHotseat.setAlpha(0f);                                                                   
3856             }                                                                                            
3857         }                                                                                                
3858     }                                                                                                    
3859                                                                                                          
3860     /**                                                                                                  
3861      * Add an item from all apps or customize onto the given workspace screen.                           
3862      * If layout is null, add to the current screen.                                                     
3863      */                                                                                                  
3864     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                           
3865         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                     
3866             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
3867         }                                                                                                
3868     }                                                                                                    
3869                                                                                                          
3870     /** Maps the current orientation to an index for referencing orientation correct global icons */     
3871     private int getCurrentOrientationIndexForGlobalIcons() {                                             
3872         // default - 0, landscape - 1                                                                    
3873         switch (getResources().getConfiguration().orientation) {                                         
3874         case Configuration.ORIENTATION_LANDSCAPE:                                                        
3875             return 1;                                                                                    
3876         default:                                                                                         
3877             return 0;                                                                                    
3878         }                                                                                                
3879     }                                                                                                    
3880                                                                                                          
3881     private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {    
3882         try {                                                                                            
3883             PackageManager packageManager = getPackageManager();                                         
3884             // Look for the toolbar icon specified in the activity meta-data                             
3885             Bundle metaData = packageManager.getActivityInfo(                                            
3886                     activityName, PackageManager.GET_META_DATA).metaData;                                
3887             if (metaData != null) {                                                                      
3888                 int iconResId = metaData.getInt(resourceName);                                           
3889                 if (iconResId != 0) {                                                                    
3890                     Resources res = packageManager.getResourcesForActivity(activityName);                
3891                     return res.getDrawable(iconResId);                                                   
3892                 }                                                                                        
3893             }                                                                                            
3894         } catch (NameNotFoundException e) {                                                              
3895             // This can happen if the activity defines an invalid drawable                               
3896             Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +           
3897                     " not found", e);                                                                    
3898         } catch (Resources.NotFoundException nfe) {                                                      
3899             // This can happen if the activity defines an invalid drawable                               
3900             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),        
3901                     nfe);                                                                                
3902         }                                                                                                
3903         return null;                                                                                     
3904     }                                                                                                    
3905                                                                                                          
3906     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3907     private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                         
3908             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3909             String toolbarResourceName) {                                                                
3910         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3911         Resources r = getResources();                                                                    
3912         int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                            
3913         int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                           
3914                                                                                                          
3915         TextView button = (TextView) findViewById(buttonId);                                             
3916         // If we were unable to find the icon via the meta-data, use a generic one                       
3917         if (toolbarIcon == null) {                                                                       
3918             toolbarIcon = r.getDrawable(fallbackDrawableId);                                             
3919             toolbarIcon.setBounds(0, 0, w, h);                                                           
3920             if (button != null) {                                                                        
3921                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3922             }                                                                                            
3923             return null;                                                                                 
3924         } else {                                                                                         
3925             toolbarIcon.setBounds(0, 0, w, h);                                                           
3926             if (button != null) {                                                                        
3927                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3928             }                                                                                            
3929             return toolbarIcon.getConstantState();                                                       
3930         }                                                                                                
3931     }                                                                                                    
3932                                                                                                          
3933     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3934     private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                             
3935             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3936             String toolbarResourceName) {                                                                
3937         ImageView button = (ImageView) findViewById(buttonId);                                           
3938         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3939                                                                                                          
3940         if (button != null) {                                                                            
3941             // If we were unable to find the icon via the meta-data, use a                               
3942             // generic one                                                                               
3943             if (toolbarIcon == null) {                                                                   
3944                 button.setImageResource(fallbackDrawableId);                                             
3945             } else {                                                                                     
3946                 button.setImageDrawable(toolbarIcon);                                                    
3947             }                                                                                            
3948         }                                                                                                
3949                                                                                                          
3950         return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                              
3951                                                                                                          
3952     }                                                                                                    
3953                                                                                                          
3954     private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                
3955         TextView button = (TextView) findViewById(buttonId);                                             
3956         button.setCompoundDrawables(d, null, null, null);                                                
3957     }                                                                                                    
3958                                                                                                          
3959     private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                      
3960         ImageView button = (ImageView) findViewById(buttonId);                                           
3961         button.setImageDrawable(d.newDrawable(getResources()));                                          
3962     }                                                                                                    
3963                                                                                                          
3964     private void invalidatePressedFocusedStates(View container, View button) {                           
3965         if (container instanceof HolographicLinearLayout) {                                              
3966             HolographicLinearLayout layout = (HolographicLinearLayout) container;                        
3967             layout.invalidatePressedFocusedStates();                                                     
3968         } else if (button instanceof HolographicImageView) {                                             
3969             HolographicImageView view = (HolographicImageView) button;                                   
3970             view.invalidatePressedFocusedStates();                                                       
3971         }                                                                                                
3972     }                                                                                                    
3973                                                                                                          
3974     public View getQsbBar() {                                                                            
3975         if (mQsb == null) {                                                                              
3976             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                         
3977             mSearchDropTargetBar.addView(mQsb);                                                          
3978         }                                                                                                
3979         return mQsb;                                                                                     
3980     }                                                                                                    
3981                                                                                                          
3982     protected boolean updateGlobalSearchIcon() {                                                         
3983         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
3984         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                     
3985         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
3986         final View voiceButton = findViewById(R.id.voice_button);                                        
3987                                                                                                          
3988         final SearchManager searchManager =                                                              
3989                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
3990         ComponentName activityName = searchManager.getGlobalSearchActivity();                            
3991         if (activityName != null) {                                                                      
3992             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
3993             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                           
3994                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,             
3995                     TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                  
3996             if (sGlobalSearchIcon[coi] == null) {                                                        
3997                 sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                       
3998                         R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,         
3999                         TOOLBAR_ICON_METADATA_NAME);                                                     
4000             }                                                                                            
4001                                                                                                          
4002             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);        
4003             searchButton.setVisibility(View.VISIBLE);                                                    
4004             invalidatePressedFocusedStates(searchButtonContainer, searchButton);                         
4005             return true;                                                                                 
4006         } else {                                                                                         
4007             // We disable both search and voice search when there is no global search provider           
4008             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);           
4009             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4010             if (searchButton != null) searchButton.setVisibility(View.GONE);                             
4011             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4012             updateVoiceButtonProxyVisible(false);                                                        
4013             return false;                                                                                
4014         }                                                                                                
4015     }                                                                                                    
4016                                                                                                          
4017     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                    
4018         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4019         final View searchButton = (ImageView) findViewById(R.id.search_button);                          
4020         updateButtonWithDrawable(R.id.search_button, d);                                                 
4021         invalidatePressedFocusedStates(searchButtonContainer, searchButton);                             
4022     }                                                                                                    
4023                                                                                                          
4024     protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                     
4025         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4026         final View voiceButton = findViewById(R.id.voice_button);                                        
4027                                                                                                          
4028         // We only show/update the voice search icon if the search icon is enabled as well               
4029         final SearchManager searchManager =                                                              
4030                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4031         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
4032                                                                                                          
4033         ComponentName activityName = null;                                                               
4034         if (globalSearchActivity != null) {                                                              
4035             // Check if the global search activity handles voice search                                  
4036             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4037             intent.setPackage(globalSearchActivity.getPackageName());                                    
4038             activityName = intent.resolveActivity(getPackageManager());                                  
4039         }                                                                                                
4040                                                                                                          
4041         if (activityName == null) {                                                                      
4042             // Fallback: check if an activity other than the global search activity                      
4043             // resolves this                                                                             
4044             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4045             activityName = intent.resolveActivity(getPackageManager());                                  
4046         }                                                                                                
4047         if (searchVisible && activityName != null) {                                                     
4048             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4049             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                            
4050                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,               
4051                     TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                            
4052             if (sVoiceSearchIcon[coi] == null) {                                                         
4053                 sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                        
4054                         R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,           
4055                         TOOLBAR_ICON_METADATA_NAME);                                                     
4056             }                                                                                            
4057             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);          
4058             voiceButton.setVisibility(View.VISIBLE);                                                     
4059             updateVoiceButtonProxyVisible(false);                                                        
4060             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                           
4061             return true;                                                                                 
4062         } else {                                                                                         
4063             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4064             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4065             updateVoiceButtonProxyVisible(false);                                                        
4066             return false;                                                                                
4067         }                                                                                                
4068     }                                                                                                    
4069                                                                                                          
4070     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                     
4071         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4072         final View voiceButton = findViewById(R.id.voice_button);                                        
4073         updateButtonWithDrawable(R.id.voice_button, d);                                                  
4074         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                               
4075     }                                                                                                    
4076                                                                                                          
4077     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                    
4078         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                             
4079         if (voiceButtonProxy != null) {                                                                  
4080             boolean visible = !forceDisableVoiceButtonProxy &&                                           
4081                     mWorkspace.shouldVoiceButtonProxyBeVisible();                                        
4082             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                          
4083             voiceButtonProxy.bringToFront();                                                             
4084         }                                                                                                
4085     }                                                                                                    
4086                                                                                                          
4087     /**                                                                                                  
4088      * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button🔵
4089      * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                      
4090      */                                                                                                  
4091     public void disableVoiceButtonProxy(boolean disabled) {                                              
4092         updateVoiceButtonProxyVisible(disabled);                                                         
4093     }                                                                                                    
4094                                                                                                          
4095     @Override                                                                                            
4096     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
4097         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
4098         final List<CharSequence> text = event.getText();                                                 
4099         text.clear();                                                                                    
4100         // Populate event with a fake title based on the current state.                                  
4101         if (mState == State.APPS_CUSTOMIZE) {                                                            
4102             text.add(mAppsCustomizeTabHost.getContentTag());                                             
4103         } else {                                                                                         
4104             text.add(getString(R.string.all_apps_home_button_label));                                    
4105         }                                                                                                
4106         return result;                                                                                   
4107     }                                                                                                    
4108                                                                                                          
4109     /**                                                                                                  
4110      * Receives notifications when system dialogs are to be closed.                                      
4111      */                                                                                                  
4112     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
4113         @Override                                                                                        
4114         public void onReceive(Context context, Intent intent) {                                          
4115             closeSystemDialogs();                                                                        
4116         }                                                                                                
4117     }                                                                                                    
4118                                                                                                          
4119     /**                                                                                                  
4120      * Receives notifications whenever the appwidgets are reset.                                         
4121      */                                                                                                  
4122     private class AppWidgetResetObserver extends ContentObserver {                                       
4123         public AppWidgetResetObserver() {                                                                
4124             super(new Handler());                                                                        
4125         }                                                                                                
4126                                                                                                          
4127         @Override                                                                                        
4128         public void onChange(boolean selfChange) {                                                       
4129             onAppWidgetReset();                                                                          
4130         }                                                                                                
4131     }                                                                                                    
4132                                                                                                          
4133     /**                                                                                                  
4134      * If the activity is currently paused, signal that we need to run the passed Runnable               
4135      * in onResume.                                                                                      
4136      *                                                                                                   
4137      * This needs to be called from incoming places where resources might have been loaded               
4138      * while we are paused.  That is becaues the Configuration might be wrong                            
4139      * when we're not running, and if it comes back to what it was when we                               
4140      * were paused, we are not restarted.                                                                
4141      *                                                                                                   
4142      * Implementation of the method from LauncherModel.Callbacks.                                        
4143      *                                                                                                   
4144      * @return true if we are currently paused.  The caller might be able to                             
4145      * skip some work in that case since we will come back again.                                        
4146      */                                                                                                  
4147     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
4148         if (mPaused) {                                                                                   
4149             Log.i(TAG, "Deferring update until onResume");                                               
4150             if (deletePreviousRunnables) {                                                               
4151                 while (mBindOnResumeCallbacks.remove(run)) {                                             
4152                 }                                                                                        
4153             }                                                                                            
4154             mBindOnResumeCallbacks.add(run);                                                             
4155             return true;                                                                                 
4156         } else {                                                                                         
4157             return false;                                                                                
4158         }                                                                                                
4159     }                                                                                                    
4160                                                                                                          
4161     private boolean waitUntilResume(Runnable run) {                                                      
4162         return waitUntilResume(run, false);                                                              
4163     }                                                                                                    
4164                                                                                                          
4165     public void addOnResumeCallback(Runnable run) {                                                      
4166         mOnResumeCallbacks.add(run);                                                                     
4167     }                                                                                                    
4168                                                                                                          
4169     /**                                                                                                  
4170      * If the activity is currently paused, signal that we need to re-run the loader                     
4171      * in onResume.                                                                                      
4172      *                                                                                                   
4173      * This needs to be called from incoming places where resources might have been loaded               
4174      * while we are paused.  That is becaues the Configuration might be wrong                            
4175      * when we're not running, and if it comes back to what it was when we                               
4176      * were paused, we are not restarted.                                                                
4177      *                                                                                                   
4178      * Implementation of the method from LauncherModel.Callbacks.                                        
4179      *                                                                                                   
4180      * @return true if we are currently paused.  The caller might be able to                             
4181      * skip some work in that case since we will come back again.                                        
4182      */                                                                                                  
4183     public boolean setLoadOnResume() {                                                                   
4184         if (mPaused) {                                                                                   
4185             Log.i(TAG, "setLoadOnResume");                                                               
4186             mOnResumeNeedsLoad = true;                                                                   
4187             return true;                                                                                 
4188         } else {                                                                                         
4189             return false;                                                                                
4190         }                                                                                                
4191     }                                                                                                    
4192                                                                                                          
4193     /**                                                                                                  
4194      * Implementation of the method from LauncherModel.Callbacks.                                        
4195      */                                                                                                  
4196     public int getCurrentWorkspaceScreen() {                                                             
4197         if (mWorkspace != null) {                                                                        
4198             return mWorkspace.getCurrentPage();                                                          
4199         } else {                                                                                         
4200             return SCREEN_COUNT / 2;                                                                     
4201         }                                                                                                
4202     }                                                                                                    
4203                                                                                                          
4204     /**                                                                                                  
4205      * Refreshes the shortcuts shown on the workspace.                                                   
4206      *                                                                                                   
4207      * Implementation of the method from LauncherModel.Callbacks.                                        
4208      */                                                                                                  
4209     public void startBinding() {                                                                         
4210         setWorkspaceLoading(true);                                                                       
4211                                                                                                          
4212         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4213         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4214         // from scratch again                                                                            
4215         mBindOnResumeCallbacks.clear();                                                                  
4216                                                                                                          
4217         // Clear the workspace because it's going to be rebound                                          
4218         mWorkspace.clearDropTargets();                                                                   
4219         mWorkspace.removeAllWorkspaceScreens();                                                          
4220                                                                                                          
4221         mWidgetsToAdvance.clear();                                                                       
4222         if (mHotseat != null) {                                                                          
4223             mHotseat.resetLayout();                                                                      
4224         }                                                                                                
4225     }                                                                                                    
4226                                                                                                          
4227     @Override                                                                                            
4228     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4229         bindAddScreens(orderedScreenIds);                                                                
4230                                                                                                          
4231         // If there are no screens, we need to have an empty screen                                      
4232         if (orderedScreenIds.size() == 0) {                                                              
4233             mWorkspace.addExtraEmptyScreen();                                                            
4234         }                                                                                                
4235                                                                                                          
4236         // Create the custom content page (this call updates mDefaultScreen which calls                  
4237         // setCurrentPage() so ensure that all pages are added before calling this).                     
4238         if (hasCustomContentToLeft()) {                                                                  
4239             mWorkspace.createCustomContentContainer();                                                   
4240             populateCustomContentContainer();                                                            
4241         }                                                                                                
4242     }                                                                                                    
4243                                                                                                          
4244     @Override                                                                                            
4245     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4246         // Log to disk                                                                                   
4247         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4248         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4249                 TextUtils.join(", ", orderedScreenIds), true);                                           
4250         int count = orderedScreenIds.size();                                                             
4251         for (int i = 0; i < count; i++) {                                                                
4252             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4253         }                                                                                                
4254     }                                                                                                    
4255                                                                                                          
4256     private boolean shouldShowWeightWatcher() {                                                          
4257         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4258         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4259         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4260                                                                                                          
4261         return show;                                                                                     
4262     }                                                                                                    
4263                                                                                                          
4264     private void toggleShowWeightWatcher() {                                                             
4265         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4266         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4267         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4268                                                                                                          
4269         show = !show;                                                                                    
4270                                                                                                          
4271         SharedPreferences.Editor editor = sp.edit();                                                     
4272         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4273         editor.commit();                                                                                 
4274                                                                                                          
4275         if (mWeightWatcher != null) {                                                                    
4276             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4277         }                                                                                                
4278     }                                                                                                    
4279                                                                                                          
4280     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4281                               final ArrayList<ItemInfo> addNotAnimated,                                  
4282                               final ArrayList<ItemInfo> addAnimated,                                     
4283                               final ArrayList<AppInfo> addedApps) {                                      
4284         Runnable r = new Runnable() {                                                                    
4285             public void run() {                                                                          
4286                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4287             }                                                                                            
4288         };                                                                                               
4289         if (waitUntilResume(r)) {                                                                        
4290             return;                                                                                      
4291         }                                                                                                
4292                                                                                                          
4293         // Add the new screens                                                                           
4294         if (newScreens != null) {                                                                        
4295             bindAddScreens(newScreens);                                                                  
4296         }                                                                                                
4297                                                                                                          
4298         // We add the items without animation on non-visible pages, and with                             
4299         // animations on the new page (which we will try and snap to).                                   
4300         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
4301             bindItems(addNotAnimated, 0,                                                                 
4302                     addNotAnimated.size(), false);                                                       
4303         }                                                                                                
4304         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
4305             bindItems(addAnimated, 0,                                                                    
4306                     addAnimated.size(), true);                                                           
4307         }                                                                                                
4308                                                                                                          
4309         // Remove the extra empty screen                                                                 
4310         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4311                                                                                                          
4312         if (!LauncherAppState.isDisableAllApps() &&                                                      
4313                 addedApps != null && mAppsCustomizeContent != null) {                                    
4314             mAppsCustomizeContent.addApps(addedApps);                                                    
4315         }                                                                                                
4316     }                                                                                                    
4317                                                                                                          
4318     /**                                                                                                  
4319      * Bind the items start-end from the list.                                                           
4320      *                                                                                                   
4321      * Implementation of the method from LauncherModel.Callbacks.                                        
4322      */                                                                                                  
4323     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4324                           final boolean forceAnimateIcons) {                                             
4325         Runnable r = new Runnable() {                                                                    
4326             public void run() {                                                                          
4327                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4328             }                                                                                            
4329         };                                                                                               
4330         if (waitUntilResume(r)) {                                                                        
4331             return;                                                                                      
4332         }                                                                                                
4333                                                                                                          
4334         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4335         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4336         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4337         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4338         Workspace workspace = mWorkspace;                                                                
4339         long newShortcutsScreenId = -1;                                                                  
4340         for (int i = start; i < end; i++) {                                                              
4341             final ItemInfo item = shortcuts.get(i);                                                      
4342                                                                                                          
4343             // Short circuit if we are loading dock items for a configuration which has no dock          
4344             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4345                     mHotseat == null) {                                                                  
4346                 continue;                                                                                
4347             }                                                                                            
4348                                                                                                          
4349             switch (item.itemType) {                                                                     
4350                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4351                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4352                     ShortcutInfo info = (ShortcutInfo) item;                                             
4353                     View shortcut = createShortcut(info);                                                
4354                                                                                                          
4355                     /*                                                                                   
4356                      * TODO: FIX collision case                                                          
4357                      */                                                                                  
4358                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4359                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4360                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4361                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4362                             Object tag = v.getTag();                                                     
4363                             String desc = "Collision while binding workspace item: " + item              
4364                                     + ". Collides with " + tag;                                          
4365                             if (LauncherAppState.isDogfoodBuild()) {                                     
4366                                 throw (new RuntimeException(desc));                                      
4367                             } else {                                                                     
4368                                 Log.d(TAG, desc);                                                        
4369                             }                                                                            
4370                         }                                                                                
4371                     }                                                                                    
4372                                                                                                          
4373                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4374                             item.cellY, 1, 1);                                                           
4375                     if (animateIcons) {                                                                  
4376                         // Animate all the applications up now                                           
4377                         shortcut.setAlpha(0f);                                                           
4378                         shortcut.setScaleX(0f);                                                          
4379                         shortcut.setScaleY(0f);                                                          
4380                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4381                         newShortcutsScreenId = item.screenId;                                            
4382                     }                                                                                    
4383                     break;                                                                               
4384                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4385                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4386                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4387                             (FolderInfo) item, mIconCache);                                              
4388                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4389                             item.cellY, 1, 1);                                                           
4390                     break;                                                                               
4391                 default:                                                                                 
4392                     throw new RuntimeException("Invalid Item Type");                                     
4393             }                                                                                            
4394         }                                                                                                
4395                                                                                                          
4396         if (animateIcons) {                                                                              
4397             // Animate to the correct page                                                               
4398             if (newShortcutsScreenId > -1) {                                                             
4399                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4400                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4401                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4402                     public void run() {                                                                  
4403                         anim.playTogether(bounceAnims);                                                  
4404                         anim.start();                                                                    
4405                     }                                                                                    
4406                 };                                                                                       
4407                 if (newShortcutsScreenId != currentScreenId) {                                           
4408                     // We post the animation slightly delayed to prevent slowdowns                       
4409                     // when we are loading right after we return to launcher.                            
4410                     mWorkspace.postDelayed(new Runnable() {                                              
4411                         public void run() {                                                              
4412                             if (mWorkspace != null) {                                                    
4413                                 mWorkspace.snapToPage(newScreenIndex);                                   
4414                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4415                                         NEW_APPS_ANIMATION_DELAY);                                       
4416                             }                                                                            
4417                         }                                                                                
4418                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4419                 } else {                                                                                 
4420                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4421                 }                                                                                        
4422             }                                                                                            
4423         }                                                                                                
4424         workspace.requestLayout();                                                                       
4425     }                                                                                                    
4426                                                                                                          
4427     /**                                                                                                  
4428      * Implementation of the method from LauncherModel.Callbacks.                                        
4429      */                                                                                                  
4430     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4431         Runnable r = new Runnable() {                                                                    
4432             public void run() {                                                                          
4433                 bindFolders(folders);                                                                    
4434             }                                                                                            
4435         };                                                                                               
4436         if (waitUntilResume(r)) {                                                                        
4437             return;                                                                                      
4438         }                                                                                                
4439         sFolders.clear();                                                                                
4440         sFolders.putAll(folders);                                                                        
4441     }                                                                                                    
4442                                                                                                          
4443     /**                                                                                                  
4444      * Add the views for a widget to the workspace.                                                      
4445      *                                                                                                   
4446      * Implementation of the method from LauncherModel.Callbacks.                                        
4447      */                                                                                                  
4448     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4449         Runnable r = new Runnable() {                                                                    
4450             public void run() {                                                                          
4451                 bindAppWidget(item);                                                                     
4452             }                                                                                            
4453         };                                                                                               
4454         if (waitUntilResume(r)) {                                                                        
4455             return;                                                                                      
4456         }                                                                                                
4457                                                                                                          
4458         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4459         if (DEBUG_WIDGETS) {                                                                             
4460             Log.d(TAG, "bindAppWidget: " + item);                                                        
4461         }                                                                                                
4462         final Workspace workspace = mWorkspace;                                                          
4463                                                                                                          
4464         AppWidgetProviderInfo appWidgetInfo;                                                             
4465         if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&               
4466                 ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                 
4467                                                                                                          
4468             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);      
4469             if (appWidgetInfo == null) {                                                                 
4470                 if (DEBUG_WIDGETS) {                                                                     
4471                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4472                             + " belongs to component " + item.providerName                               
4473                             + ", as the povider is null");                                               
4474                 }                                                                                        
4475                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4476                 return;                                                                                  
4477             }                                                                                            
4478             // Note: This assumes that the id remap broadcast is received before this step.              
4479             // If that is not the case, the id remap will be ignored and user may see the                
4480             // click to setup view.                                                                      
4481             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);      
4482             pendingInfo.spanX = item.spanX;                                                              
4483             pendingInfo.spanY = item.spanY;                                                              
4484             pendingInfo.minSpanX = item.minSpanX;                                                        
4485             pendingInfo.minSpanY = item.minSpanY;                                                        
4486             Bundle options =                                                                             
4487                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
4488                                                                                                          
4489             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4490             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4491                     newWidgetId, appWidgetInfo, options);                                                
4492                                                                                                          
4493             // TODO consider showing a permission dialog when the widget is clicked.                     
4494             if (!success) {                                                                              
4495                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4496                 if (DEBUG_WIDGETS) {                                                                     
4497                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4498                             + " belongs to component " + item.providerName                               
4499                             + ", as the launcher is unable to bing a new widget id");                    
4500                 }                                                                                        
4501                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4502                 return;                                                                                  
4503             }                                                                                            
4504                                                                                                          
4505             item.appWidgetId = newWidgetId;                                                              
4506                                                                                                          
4507             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4508             // the widget is ready to go.                                                                
4509             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4510                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4511                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4512                                                                                                          
4513             LauncherModel.updateItemInDatabase(this, item);                                              
4514         }                                                                                                
4515                                                                                                          
4516         if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                             
4517             final int appWidgetId = item.appWidgetId;                                                    
4518             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
4519             if (DEBUG_WIDGETS) {                                                                         
4520                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidget🔵
4521             }                                                                                            
4522                                                                                                          
4523             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4524         } else {                                                                                         
4525             appWidgetInfo = null;                                                                        
4526             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                    
4527             view.updateIcon(mIconCache);                                                                 
4528             item.hostView = view;                                                                        
4529             item.hostView.updateAppWidget(null);                                                         
4530             item.hostView.setOnClickListener(this);                                                      
4531         }                                                                                                
4532                                                                                                          
4533         item.hostView.setTag(item);                                                                      
4534         item.onBindAppWidget(this);                                                                      
4535                                                                                                          
4536         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4537                 item.cellY, item.spanX, item.spanY, false);                                              
4538         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
4539                                                                                                          
4540         workspace.requestLayout();                                                                       
4541                                                                                                          
4542         if (DEBUG_WIDGETS) {                                                                             
4543             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4544                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4545         }                                                                                                
4546     }                                                                                                    
4547                                                                                                          
4548     /**                                                                                                  
4549      * Restores a pending widget.                                                                        
4550      *                                                                                                   
4551      * @param appWidgetId The app widget id                                                              
4552      * @param cellInfo The position on screen where to create the widget.                                
4553      */                                                                                                  
4554     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4555         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4556         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4557             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4558             return;                                                                                      
4559         }                                                                                                
4560                                                                                                          
4561         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4562         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4563                                                                                                          
4564         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4565         LauncherModel.updateItemInDatabase(this, info);                                                  
4566     }                                                                                                    
4567                                                                                                          
4568     public void onPageBoundSynchronously(int page) {                                                     
4569         mSynchronouslyBoundPages.add(page);                                                              
4570     }                                                                                                    
4571                                                                                                          
4572     /**                                                                                                  
4573      * Callback saying that there aren't any more items to bind.                                         
4574      *                                                                                                   
4575      * Implementation of the method from LauncherModel.Callbacks.                                        
4576      */                                                                                                  
4577     public void finishBindingItems(final boolean upgradePath) {                                          
4578         Runnable r = new Runnable() {                                                                    
4579             public void run() {                                                                          
4580                 finishBindingItems(upgradePath);                                                         
4581             }                                                                                            
4582         };                                                                                               
4583         if (waitUntilResume(r)) {                                                                        
4584             return;                                                                                      
4585         }                                                                                                
4586         if (mSavedState != null) {                                                                       
4587             if (!mWorkspace.hasFocus()) {                                                                
4588                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4589             }                                                                                            
4590             mSavedState = null;                                                                          
4591         }                                                                                                
4592                                                                                                          
4593         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4594                                                                                                          
4595         setWorkspaceLoading(false);                                                                      
4596         sendLoadingCompleteBroadcastIfNecessary();                                                       
4597                                                                                                          
4598         // If we received the result of any pending adds while the loader was running (e.g. the          
4599         // widget configuration forced an orientation change), process them now.                         
4600         if (sPendingAddItem != null) {                                                                   
4601             final long screenId = completeAdd(sPendingAddItem);                                          
4602                                                                                                          
4603             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4604             // the screen would be guaranteed to exist after bind, and the page would be set through     
4605             // the workspace restore process.                                                            
4606             mWorkspace.post(new Runnable() {                                                             
4607                 @Override                                                                                
4608                 public void run() {                                                                      
4609                     mWorkspace.snapToScreenId(screenId);                                                 
4610                 }                                                                                        
4611             });                                                                                          
4612             sPendingAddItem = null;                                                                      
4613         }                                                                                                
4614                                                                                                          
4615         if (upgradePath) {                                                                               
4616             mWorkspace.getUniqueComponents(true, null);                                                  
4617             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4618         }                                                                                                
4619         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4620         mModel.recheckRestoredItems(this);                                                               
4621     }                                                                                                    
4622                                                                                                          
4623     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4624         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4625             String permission =                                                                          
4626                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4627             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4628             sendBroadcast(intent, permission);                                                           
4629             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4630             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4631             editor.apply();                                                                              
4632         }                                                                                                
4633     }                                                                                                    
4634                                                                                                          
4635     public boolean isAllAppsButtonRank(int rank) {                                                       
4636         if (mHotseat != null) {                                                                          
4637             return mHotseat.isAllAppsButtonRank(rank);                                                   
4638         }                                                                                                
4639         return false;                                                                                    
4640     }                                                                                                    
4641                                                                                                          
4642     private boolean canRunNewAppsAnimation() {                                                           
4643         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4644         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4645     }                                                                                                    
4646                                                                                                          
4647     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4648         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4649                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4650                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4651                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4652         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4653         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4654         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4655         return bounceAnim;                                                                               
4656     }                                                                                                    
4657                                                                                                          
4658     public boolean useVerticalBarLayout() {                                                              
4659         return LauncherAppState.getInstance().getDynamicGrid().                                          
4660                 getDeviceProfile().isVerticalBarLayout();                                                
4661     }                                                                                                    
4662                                                                                                          
4663     protected Rect getSearchBarBounds() {                                                                
4664         return LauncherAppState.getInstance().getDynamicGrid().                                          
4665                 getDeviceProfile().getSearchBarBounds();                                                 
4666     }                                                                                                    
4667                                                                                                          
4668     @Override                                                                                            
4669     public void bindSearchablesChanged() {                                                               
4670         boolean searchVisible = updateGlobalSearchIcon();                                                
4671         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
4672         if (mSearchDropTargetBar != null) {                                                              
4673             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
4674         }                                                                                                
4675     }                                                                                                    
4676                                                                                                          
4677     /**                                                                                                  
4678      * Add the icons for all apps.                                                                       
4679      *                                                                                                   
4680      * Implementation of the method from LauncherModel.Callbacks.                                        
4681      */                                                                                                  
4682     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4683         if (LauncherAppState.isDisableAllApps()) {                                                       
4684             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4685                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4686                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4687                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4688                 }                                                                                        
4689                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4690             }                                                                                            
4691             if (mAppsCustomizeContent != null) {                                                         
4692                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4693                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4694             }                                                                                            
4695         } else {                                                                                         
4696             if (mAppsCustomizeContent != null) {                                                         
4697                 mAppsCustomizeContent.setApps(apps);                                                     
4698                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4699                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4700             }                                                                                            
4701         }                                                                                                
4702     }                                                                                                    
4703                                                                                                          
4704     /**                                                                                                  
4705      * A package was updated.                                                                            
4706      *                                                                                                   
4707      * Implementation of the method from LauncherModel.Callbacks.                                        
4708      */                                                                                                  
4709     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4710         Runnable r = new Runnable() {                                                                    
4711             public void run() {                                                                          
4712                 bindAppsUpdated(apps);                                                                   
4713             }                                                                                            
4714         };                                                                                               
4715         if (waitUntilResume(r)) {                                                                        
4716             return;                                                                                      
4717         }                                                                                                
4718                                                                                                          
4719         if (mWorkspace != null) {                                                                        
4720             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4721         }                                                                                                
4722                                                                                                          
4723         if (!LauncherAppState.isDisableAllApps() &&                                                      
4724                 mAppsCustomizeContent != null) {                                                         
4725             mAppsCustomizeContent.updateApps(apps);                                                      
4726         }                                                                                                
4727     }                                                                                                    
4728                                                                                                          
4729     /**                                                                                                  
4730 <<<<<<< GitAnalyzerPlus_ours                                                                             
4731      * Some shortcuts were updated in the background.                                                    
4732      *                                                                                                   
4733      * Implementation of the method from LauncherModel.Callbacks.                                        
4734      */                                                                                                  
4735     public void bindShortcutsUpdated(final ArrayList<ShortcutInfo> shortcuts) {                          
4736         Runnable r = new Runnable() {                                                                    
4737             public void run() {                                                                          
4738                 bindShortcutsUpdated(shortcuts);                                                         
4739             }                                                                                            
4740         };                                                                                               
4741         if (waitUntilResume(r)) {                                                                        
4742             return;                                                                                      
4743         }                                                                                                
4744                                                                                                          
4745         if (mWorkspace != null) {                                                                        
4746             mWorkspace.updateShortcuts(shortcuts);                                                       
4747 ||||||| GitAnalyzerPlus_base                                                                             
4748      *                                                                                                   
4749      * Implementation of the method from LauncherModel.Callbacks.                                        
4750      */                                                                                                  
4751     @Override                                                                                            
4752     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4753         if (mWorkspace != null) {                                                                        
4754             mWorkspace.updatePackageState(installInfo);                                                  
4755         }                                                                                                
4756     }                                                                                                    
4757                                                                                                          
4758     /**                                                                                                  
4759      * Update the label and icon of all the icons in a package                                           
4760      *                                                                                                   
4761      * Implementation of the method from LauncherModel.Callbacks.                                        
4762      */                                                                                                  
4763     @Override                                                                                            
4764     public void updatePackageBadge(String packageName) {                                                 
4765         if (mWorkspace != null) {                                                                        
4766             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4767         }                                                                                                
4768     }                                                                                                    
4769                                                                                                          
4770 =======                                                                                                  
4771      * Packages were restored                                                                            
4772      */                                                                                                  
4773     public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                        
4774         Runnable r = new Runnable() {                                                                    
4775             public void run() {                                                                          
4776                 bindAppsRestored(apps);                                                                  
4777             }                                                                                            
4778         };                                                                                               
4779         if (waitUntilResume(r)) {                                                                        
4780             return;                                                                                      
4781         }                                                                                                
4782                                                                                                          
4783         if (mWorkspace != null) {                                                                        
4784             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4785 >>>>>>> GitAnalyzerPlus_theirs                                                                           
4786         }                                                                                                
4787     }                                                                                                    
4788                                                                                                          
4789     /**                                                                                                  
4790      * Update the state of a package, typically related to install state.                                
4791      *                                                                                                   
4792      * Implementation of the method from LauncherModel.Callbacks.                                        
4793      */                                                                                                  
4794     @Override                                                                                            
4795     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4796         if (mWorkspace != null) {                                                                        
4797             mWorkspace.updatePackageState(installInfo);                                                  
4798         }                                                                                                
4799     }                                                                                                    
4800                                                                                                          
4801     /**                                                                                                  
4802      * Update the label and icon of all the icons in a package                                           
4803      *                                                                                                   
4804      * Implementation of the method from LauncherModel.Callbacks.                                        
4805      */                                                                                                  
4806     @Override                                                                                            
4807     public void updatePackageBadge(String packageName) {                                                 
4808         if (mWorkspace != null) {                                                                        
4809             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4810         }                                                                                                
4811     }                                                                                                    
4812                                                                                                          
4813     /**                                                                                                  
4814      * A package was uninstalled.  We take both the super set of packageNames                            
4815      * in addition to specific applications to remove, the reason being that                             
4816      * this can be called when a package is updated as well.  In that scenario,                          
4817      * we only remove specific components from the workspace, where as                                   
4818      * package-removal should clear all items by package name.                                           
4819      *                                                                                                   
4820      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4821      * Implementation of the method from LauncherModel.Callbacks.                                        
4822      */                                                                                                  
4823     @Override                                                                                            
4824     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4825             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4826         Runnable r = new Runnable() {                                                                    
4827             public void run() {                                                                          
4828                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4829             }                                                                                            
4830         };                                                                                               
4831         if (waitUntilResume(r)) {                                                                        
4832             return;                                                                                      
4833         }                                                                                                
4834                                                                                                          
4835         if (reason == 0) {                                                                               
4836             if (!packageNames.isEmpty()) {                                                               
4837                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4838             }                                                                                            
4839             if (!appInfos.isEmpty()) {                                                                   
4840                 mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                 
4841             }                                                                                            
4842         } else {                                                                                         
4843             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4844         }                                                                                                
4845                                                                                                          
4846         // Notify the drag controller                                                                    
4847         mDragController.onAppsRemoved(packageNames, appInfos);                                           
4848                                                                                                          
4849         // Update AllApps                                                                                
4850         if (!LauncherAppState.isDisableAllApps() &&                                                      
4851                 mAppsCustomizeContent != null) {                                                         
4852             mAppsCustomizeContent.removeApps(appInfos);                                                  
4853         }                                                                                                
4854     }                                                                                                    
4855                                                                                                          
4856     /**                                                                                                  
4857      * A number of packages were updated.                                                                
4858      */                                                                                                  
4859     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4860     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4861             public void run() {                                                                          
4862                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4863                 mWidgetsAndShortcuts = null;                                                             
4864             }                                                                                            
4865         };                                                                                               
4866     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4867         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4868             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4869             return;                                                                                      
4870         }                                                                                                
4871                                                                                                          
4872         // Update the widgets pane                                                                       
4873         if (mAppsCustomizeContent != null) {                                                             
4874             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4875         }                                                                                                
4876     }                                                                                                    
4877                                                                                                          
4878     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4879         final Display d = getWindowManager().getDefaultDisplay();                                        
4880         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4881         switch (d.getRotation()) {                                                                       
4882         case Surface.ROTATION_0:                                                                         
4883         case Surface.ROTATION_180:                                                                       
4884             // We are currently in the same basic orientation as the natural orientation                 
4885             naturalOri = configOri;                                                                      
4886             break;                                                                                       
4887         case Surface.ROTATION_90:                                                                        
4888         case Surface.ROTATION_270:                                                                       
4889             // We are currently in the other basic orientation to the natural orientation                
4890             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4891                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4892             break;                                                                                       
4893         }                                                                                                
4894                                                                                                          
4895         int[] oriMap = {                                                                                 
4896                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4897                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4898                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4899                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4900         };                                                                                               
4901         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4902         // is landscape.                                                                                 
4903         int indexOffset = 0;                                                                             
4904         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4905             indexOffset = 1;                                                                             
4906         }                                                                                                
4907         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4908     }                                                                                                    
4909                                                                                                          
4910     public boolean isRotationEnabled() {                                                                 
4911         boolean enableRotation = sForceEnableRotation ||                                                 
4912                 getResources().getBoolean(R.bool.allow_rotation);                                        
4913         return enableRotation;                                                                           
4914     }                                                                                                    
4915     public void lockScreenOrientation() {                                                                
4916         if (isRotationEnabled()) {                                                                       
4917             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                    
4918                     .getConfiguration().orientation));                                                   
4919         }                                                                                                
4920     }                                                                                                    
4921     public void unlockScreenOrientation(boolean immediate) {                                             
4922         if (isRotationEnabled()) {                                                                       
4923             if (immediate) {                                                                             
4924                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4925             } else {                                                                                     
4926                 mHandler.postDelayed(new Runnable() {                                                    
4927                     public void run() {                                                                  
4928                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4929                     }                                                                                    
4930                 }, mRestoreScreenOrientationDelay);                                                      
4931             }                                                                                            
4932         }                                                                                                
4933     }                                                                                                    
4934                                                                                                          
4935     /**                                                                                                  
4936      * Called when the SearchBar hint should be changed.                                                 
4937      *                                                                                                   
4938      * @param hint the hint to be displayed in the search bar.                                           
4939      */                                                                                                  
4940     protected void onSearchBarHintChanged(String hint) {                                                 
4941                                                                                                          
4942     }                                                                                                    
4943                                                                                                          
4944     protected boolean isLauncherPreinstalled() {                                                         
4945         PackageManager pm = getPackageManager();                                                         
4946         try {                                                                                            
4947             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4948             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4949                 return true;                                                                             
4950             } else {                                                                                     
4951                 return false;                                                                            
4952             }                                                                                            
4953         } catch (NameNotFoundException e) {                                                              
4954             e.printStackTrace();                                                                         
4955             return false;                                                                                
4956         }                                                                                                
4957     }                                                                                                    
4958                                                                                                          
4959     /**                                                                                                  
4960      * This method indicates whether or not we should suggest default wallpaper dimensions               
4961      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4962      */                                                                                                  
4963     protected boolean overrideWallpaperDimensions() {                                                    
4964         return true;                                                                                     
4965     }                                                                                                    
4966                                                                                                          
4967     /**                                                                                                  
4968      * To be overridden by subclasses to indicate that there is an activity to launch                    
4969      * before showing the standard launcher experience.                                                  
4970      */                                                                                                  
4971     protected boolean hasFirstRunActivity() {                                                            
4972         return false;                                                                                    
4973     }                                                                                                    
4974                                                                                                          
4975     /**                                                                                                  
4976      * To be overridden by subclasses to launch any first run activity                                   
4977      */                                                                                                  
4978     protected Intent getFirstRunActivity() {                                                             
4979         return null;                                                                                     
4980     }                                                                                                    
4981                                                                                                          
4982     private boolean shouldRunFirstRunActivity() {                                                        
4983         return !ActivityManager.isRunningInTestHarness() &&                                              
4984                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4985     }                                                                                                    
4986                                                                                                          
4987     protected boolean hasRunFirstRunActivity() {                                                         
4988         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4989     }                                                                                                    
4990                                                                                                          
4991     public boolean showFirstRunActivity() {                                                              
4992         if (shouldRunFirstRunActivity() &&                                                               
4993                 hasFirstRunActivity()) {                                                                 
4994             Intent firstRunIntent = getFirstRunActivity();                                               
4995             if (firstRunIntent != null) {                                                                
4996                 startActivity(firstRunIntent);                                                           
4997                 markFirstRunActivityShown();                                                             
4998                 return true;                                                                             
4999             }                                                                                            
5000         }                                                                                                
5001         return false;                                                                                    
5002     }                                                                                                    
5003                                                                                                          
5004     private void markFirstRunActivityShown() {                                                           
5005         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5006         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
5007         editor.apply();                                                                                  
5008     }                                                                                                    
5009                                                                                                          
5010     /**                                                                                                  
5011      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
5012      * screen that must be displayed and dismissed.                                                      
5013      */                                                                                                  
5014     protected boolean hasDismissableIntroScreen() {                                                      
5015         return false;                                                                                    
5016     }                                                                                                    
5017                                                                                                          
5018     /**                                                                                                  
5019      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
5020      */                                                                                                  
5021     protected View getIntroScreen() {                                                                    
5022         return null;                                                                                     
5023     }                                                                                                    
5024                                                                                                          
5025     /**                                                                                                  
5026      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
5027      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
5028      */                                                                                                  
5029     private boolean shouldShowIntroScreen() {                                                            
5030         return hasDismissableIntroScreen() &&                                                            
5031                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
5032     }                                                                                                    
5033                                                                                                          
5034     protected void showIntroScreen() {                                                                   
5035         View introScreen = getIntroScreen();                                                             
5036         changeWallpaperVisiblity(false);                                                                 
5037         if (introScreen != null) {                                                                       
5038             mDragLayer.showOverlayView(introScreen);                                                     
5039         }                                                                                                
5040     }                                                                                                    
5041                                                                                                          
5042     public void dismissIntroScreen() {                                                                   
5043         markIntroScreenDismissed();                                                                      
5044         if (showFirstRunActivity()) {                                                                    
5045             // We delay hiding the intro view until the first run activity is showing. This              
5046             // avoids a blip.                                                                            
5047             mWorkspace.postDelayed(new Runnable() {                                                      
5048                 @Override                                                                                
5049                 public void run() {                                                                      
5050                     mDragLayer.dismissOverlayView();                                                     
5051                     showFirstRunClings();                                                                
5052                 }                                                                                        
5053             }, ACTIVITY_START_DELAY);                                                                    
5054         } else {                                                                                         
5055             mDragLayer.dismissOverlayView();                                                             
5056             showFirstRunClings();                                                                        
5057         }                                                                                                
5058         changeWallpaperVisiblity(true);                                                                  
5059     }                                                                                                    
5060                                                                                                          
5061     private void markIntroScreenDismissed() {                                                            
5062         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5063         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
5064         editor.apply();                                                                                  
5065     }                                                                                                    
5066                                                                                                          
5067     private void showFirstRunClings() {                                                                  
5068         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
5069         // on the device, then we always show the first run cling experience (or if there is no          
5070         // launcher2). Otherwise, we prompt the user upon started for migration                          
5071         LauncherClings launcherClings = new LauncherClings(this);                                        
5072         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
5073             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
5074                 launcherClings.showMigrationCling();                                                     
5075             } else {                                                                                     
5076                 launcherClings.showLongPressCling(true);                                                 
5077             }                                                                                            
5078         }                                                                                                
5079     }                                                                                                    
5080                                                                                                          
5081     void showWorkspaceSearchAndHotseat() {                                                               
5082         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
5083         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
5084         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
5085         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
5086     }                                                                                                    
5087                                                                                                          
5088     void hideWorkspaceSearchAndHotseat() {                                                               
5089         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
5090         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
5091         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
5092         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
5093     }                                                                                                    
5094                                                                                                          
5095     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
5096         // Called from search suggestion, not supported in other profiles.                               
5097         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
5098         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
5099         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
5100                 myUser);                                                                                 
5101         if (activityInfo == null) {                                                                      
5102             return null;                                                                                 
5103         }                                                                                                
5104         return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                
5105     }                                                                                                    
5106                                                                                                          
5107     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5108             Bitmap icon) {                                                                               
5109         // Called from search suggestion, not supported in other profiles.                               
5110         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
5111                 UserHandleCompat.myUserHandle());                                                        
5112     }                                                                                                    
5113                                                                                                          
5114     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5115             Bitmap icon, UserHandleCompat user) {                                                        
5116         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
5117         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
5118         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
5119     }                                                                                                    
5120                                                                                                          
5121     protected void moveWorkspaceToDefaultScreen() {                                                      
5122         mWorkspace.moveToDefaultScreen(false);                                                           
5123     }                                                                                                    
5124                                                                                                          
5125     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
5126         dragView.setTag(dragInfo);                                                                       
5127         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
5128         mWorkspace.beginExternalDragShared(dragView, source);                                            
5129     }                                                                                                    
5130                                                                                                          
5131     @Override                                                                                            
5132     public void onPageSwitch(View newPage, int newPageIndex) {                                           
5133     }                                                                                                    
5134                                                                                                          
5135     /**                                                                                                  
5136      * Prints out out state for debugging.                                                               
5137      */                                                                                                  
5138     public void dumpState() {                                                                            
5139         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
5140         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
5141         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
5142         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
5143         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
5144         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
5145         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
5146         mModel.dumpState();                                                                              
5147                                                                                                          
5148         if (mAppsCustomizeContent != null) {                                                             
5149             mAppsCustomizeContent.dumpState();                                                           
5150         }                                                                                                
5151         Log.d(TAG, "END launcher3 dump state");                                                          
5152     }                                                                                                    
5153                                                                                                          
5154     @Override                                                                                            
5155     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
5156         super.dump(prefix, fd, writer, args);                                                            
5157         synchronized (sDumpLogs) {                                                                       
5158             writer.println(" ");                                                                         
5159             writer.println("Debug logs: ");                                                              
5160             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
5161                 writer.println("  " + sDumpLogs.get(i));                                                 
5162             }                                                                                            
5163         }                                                                                                
5164     }                                                                                                    
5165                                                                                                          
5166     public static void dumpDebugLogsToConsole() {                                                        
5167         if (DEBUG_DUMP_LOG) {                                                                            
5168             synchronized (sDumpLogs) {                                                                   
5169                 Log.d(TAG, "");                                                                          
5170                 Log.d(TAG, "*********************");                                                     
5171                 Log.d(TAG, "Launcher debug logs: ");                                                     
5172                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
5173                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
5174                 }                                                                                        
5175                 Log.d(TAG, "*********************");                                                     
5176                 Log.d(TAG, "");                                                                          
5177             }                                                                                            
5178         }                                                                                                
5179     }                                                                                                    
5180                                                                                                          
5181     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
5182         addDumpLog(tag, log, null, debugLog);                                                            
5183     }                                                                                                    
5184                                                                                                          
5185     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
5186         if (debugLog) {                                                                                  
5187             if (e != null) {                                                                             
5188                 Log.d(tag, log, e);                                                                      
5189             } else {                                                                                     
5190                 Log.d(tag, log);                                                                         
5191             }                                                                                            
5192         }                                                                                                
5193         if (DEBUG_DUMP_LOG) {                                                                            
5194             sDateStamp.setTime(System.currentTimeMillis());                                              
5195             synchronized (sDumpLogs) {                                                                   
5196                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
5197                     + (e == null ? "" : (", Exception: " + e)));                                         
5198             }                                                                                            
5199         }                                                                                                
5200     }                                                                                                    
5201                                                                                                          
5202     public void dumpLogsToLocalData() {                                                                  
5203         if (DEBUG_DUMP_LOG) {                                                                            
5204             new AsyncTask<Void, Void, Void>() {                                                          
5205                 public Void doInBackground(Void ... args) {                                              
5206                     boolean success = false;                                                             
5207                     sDateStamp.setTime(sRunStart);                                                       
5208                     String FILENAME = sDateStamp.getMonth() + "-"                                        
5209                             + sDateStamp.getDay() + "_"                                                  
5210                             + sDateStamp.getHours() + "-"                                                
5211                             + sDateStamp.getMinutes() + "_"                                              
5212                             + sDateStamp.getSeconds() + ".txt";                                          
5213                                                                                                          
5214                     FileOutputStream fos = null;                                                         
5215                     File outFile = null;                                                                 
5216                     try {                                                                                
5217                         outFile = new File(getFilesDir(), FILENAME);                                     
5218                         outFile.createNewFile();                                                         
5219                         fos = new FileOutputStream(outFile);                                             
5220                     } catch (Exception e) {                                                              
5221                         e.printStackTrace();                                                             
5222                     }                                                                                    
5223                     if (fos != null) {                                                                   
5224                         PrintWriter writer = new PrintWriter(fos);                                       
5225                                                                                                          
5226                         writer.println(" ");                                                             
5227                         writer.println("Debug logs: ");                                                  
5228                         synchronized (sDumpLogs) {                                                       
5229                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
5230                                 writer.println("  " + sDumpLogs.get(i));                                 
5231                             }                                                                            
5232                         }                                                                                
5233                         writer.close();                                                                  
5234                     }                                                                                    
5235                     try {                                                                                
5236                         if (fos != null) {                                                               
5237                             fos.close();                                                                 
5238                             success = true;                                                              
5239                         }                                                                                
5240                     } catch (IOException e) {                                                            
5241                         e.printStackTrace();                                                             
5242                     }                                                                                    
5243                     return null;                                                                         
5244                 }                                                                                        
5245             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
5246         }                                                                                                
5247     }                                                                                                    
5248 }                                                                                                        
5249                                                                                                          
5250 interface LauncherTransitionable {                                                                       
5251     View getContent();                                                                                   
5252     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
5253     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
5254     void onLauncherTransitionStep(Launcher l, float t);                                                  
5255     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
5256 }                                                                                                        
5257                                                                                                          
5258 interface DebugIntents {                                                                                 
5259     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
5260     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
5261 }                                                                                                        






























































   1                                                                                                          
   2 /*                                                                                                       
   3  * Copyright (C) 2008 The Android Open Source Project                                                    
   4  *                                                                                                       
   5  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   6  * you may not use this file except in compliance with the License.                                      
   7  * You may obtain a copy of the License at                                                               
   8  *                                                                                                       
   9  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
  10  *                                                                                                       
  11  * Unless required by applicable law or agreed to in writing, software                                   
  12  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  14  * See the License for the specific language governing permissions and                                   
  15  * limitations under the License.                                                                        
  16  */                                                                                                      
  17                                                                                                          
  18 package com.android.launcher3;                                                                           
  19                                                                                                          
  20 import android.animation.Animator;                                                                       
  21 import android.animation.AnimatorListenerAdapter;                                                        
  22 import android.animation.AnimatorSet;                                                                    
  23 import android.animation.ObjectAnimator;                                                                 
  24 import android.animation.PropertyValuesHolder;                                                           
  25 import android.animation.TimeInterpolator;                                                               
  26 import android.animation.ValueAnimator;                                                                  
  27 import android.annotation.TargetApi;                                                                     
  28 import android.app.Activity;                                                                             
  29 import android.app.ActivityManager;                                                                      
  30 import android.app.ActivityOptions;                                                                      
  31 import android.app.AlertDialog;                                                                          
  32 import android.app.SearchManager;                                                                        
  33 import android.appwidget.AppWidgetHostView;                                                              
  34 import android.appwidget.AppWidgetManager;                                                               
  35 import android.appwidget.AppWidgetProviderInfo;                                                          
  36 import android.content.ActivityNotFoundException;                                                        
  37 import android.content.BroadcastReceiver;                                                                
  38 import android.content.ComponentCallbacks2;                                                              
  39 import android.content.ComponentName;                                                                    
  40 import android.content.ContentResolver;                                                                  
  41 import android.content.Context;                                                                          
  42 import android.content.DialogInterface;                                                                  
  43 import android.content.Intent;                                                                           
  44 import android.content.IntentFilter;                                                                     
  45 import android.content.SharedPreferences;                                                                
  46 import android.content.pm.ActivityInfo;                                                                  
  47 import android.content.pm.ApplicationInfo;                                                               
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.pm.PackageManager.NameNotFoundException;                                          
  50 import android.content.res.Configuration;                                                                
  51 import android.content.res.Resources;                                                                    
  52 import android.database.ContentObserver;                                                                 
  53 import android.graphics.Bitmap;                                                                          
  54 import android.graphics.Canvas;                                                                          
  55 import android.graphics.Color;                                                                           
  56 import android.graphics.Point;                                                                           
  57 import android.graphics.PorterDuff;                                                                      
  58 import android.graphics.Rect;                                                                            
  59 import android.graphics.drawable.Drawable;                                                               
  60 import android.net.Uri;                                                                                  
  61 import android.os.AsyncTask;                                                                             
  62 import android.os.Build;                                                                                 
  63 import android.os.Bundle;                                                                                
  64 import android.os.Environment;                                                                           
  65 import android.os.Handler;                                                                               
  66 import android.os.Message;                                                                               
  67 import android.os.StrictMode;                                                                            
  68 import android.os.SystemClock;                                                                           
  69 import android.speech.RecognizerIntent;                                                                  
  70 import android.text.Selection;                                                                           
  71 import android.text.SpannableStringBuilder;                                                              
  72 import android.text.TextUtils;                                                                           
  73 import android.text.method.TextKeyListener;                                                              
  74 import android.util.DisplayMetrics;                                                                      
  75 import android.util.Log;                                                                                 
  76 import android.view.Display;                                                                             
  77 import android.view.Gravity;                                                                             
  78 import android.view.HapticFeedbackConstants;                                                             
  79 import android.view.KeyEvent;                                                                            
  80 import android.view.LayoutInflater;                                                                      
  81 import android.view.Menu;                                                                                
  82 import android.view.MotionEvent;                                                                         
  83 import android.view.Surface;                                                                             
  84 import android.view.View;                                                                                
  85 import android.view.View.OnClickListener;                                                                
  86 import android.view.View.OnLongClickListener;                                                            
  87 import android.view.ViewAnimationUtils;                                                                  
  88 import android.view.ViewGroup;                                                                           
  89 import android.view.ViewTreeObserver;                                                                    
  90 import android.view.Window;                                                                              
  91 import android.view.WindowManager;                                                                       
  92 import android.view.accessibility.AccessibilityEvent;                                                    
  93 import android.view.animation.AccelerateInterpolator;                                                    
  94 import android.view.animation.DecelerateInterpolator;                                                    
  95 import android.view.inputmethod.InputMethodManager;                                                      
  96 import android.widget.Advanceable;                                                                       
  97 import android.widget.FrameLayout;                                                                       
  98 import android.widget.ImageView;                                                                         
  99 import android.widget.TextView;                                                                          
 100 import android.widget.Toast;                                                                             
 101                                                                                                          
 102 import com.android.launcher3.DropTarget.DragObject;                                                      
 103 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 104 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 105 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 106 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 107 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 108 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 109 import com.android.launcher3.compat.UserHandleCompat;                                                    
 110 import com.android.launcher3.compat.UserManagerCompat;                                                   
 111                                                                                                          
 112 import java.io.DataInputStream;                                                                          
 113 import java.io.DataOutputStream;                                                                         
 114 import java.io.File;                                                                                     
 115 import java.io.FileDescriptor;                                                                           
 116 import java.io.FileNotFoundException;                                                                    
 117 import java.io.FileOutputStream;                                                                         
 118 import java.io.IOException;                                                                              
 119 import java.io.PrintWriter;                                                                              
 120 import java.lang.reflect.Field;                                                                          
 121 import java.lang.reflect.InvocationTargetException;                                                      
 122 import java.lang.reflect.Method;                                                                         
 123 import java.text.DateFormat;                                                                             
 124 import java.util.ArrayList;                                                                              
 125 import java.util.Collection;                                                                             
 126 import java.util.Date;                                                                                   
 127 import java.util.HashMap;                                                                                
 128 import java.util.List;                                                                                   
 129 import java.util.concurrent.atomic.AtomicInteger;                                                        
 130                                                                                                          
 131 /**                                                                                                      
 132  * Default launcher application.                                                                         
 133  */                                                                                                      
 134 public class Launcher extends Activity                                                                   
 135         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 136                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {            
 137     static final String TAG = "Launcher";                                                                
 138     static final boolean LOGD = false;                                                                   
 139                                                                                                          
 140     static final boolean PROFILE_STARTUP = false;                                                        
 141     static final boolean DEBUG_WIDGETS = false;                                                          
 142     static final boolean DEBUG_STRICT_MODE = false;                                                      
 143     static final boolean DEBUG_RESUME_TIME = false;                                                      
 144     static final boolean DEBUG_DUMP_LOG = false;                                                         
 145                                                                                                          
 146     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 147                                                                                                          
 148     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 149     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 150     private static final int REQUEST_PICK_SHORTCUT = 7;                                                  
 151     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 152     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 153                                                                                                          
 154     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 155     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 156                                                                                                          
 157     /**                                                                                                  
 158      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 159      * request codes used internally.                                                                    
 160      */                                                                                                  
 161     protected static final int REQUEST_LAST = 100;                                                       
 162                                                                                                          
 163     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 164                                                                                                          
 165     static final int SCREEN_COUNT = 5;                                                                   
 166     static final int DEFAULT_SCREEN = 2;                                                                 
 167                                                                                                          
 168     // To turn on these properties, type                                                                 
 169     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 170     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                        
 171     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 172     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                
 173                                                                                                          
 174     // The Intent extra that defines whether to ignore the launch animation                              
 175     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 176             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 177                                                                                                          
 178     // Type: int                                                                                         
 179     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 180     // Type: int                                                                                         
 181     private static final String RUNTIME_STATE = "launcher.state";                                        
 182     // Type: int                                                                                         
 183     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 190     // Type: boolean                                                                                     
 191     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 192     // Type: long                                                                                        
 193     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 194     // Type: int                                                                                         
 195     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 196     // Type: int                                                                                         
 197     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 198     // Type: parcelable                                                                                  
 199     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 200     // Type: parcelable                                                                                  
 201     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 202     // Type: int[]                                                                                       
 203     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 204                                                                                                          
 205     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 206     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 207                                                                                                          
 208     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 209     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 210             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 211                                                                                                          
 212     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";        
 213     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                      
 214             "com.android.launcher.toolbar_search_icon";                                                  
 215     private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                
 216             "com.android.launcher.toolbar_voice_search_icon";                                            
 217                                                                                                          
 218     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 219     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 220                                                                                                          
 221     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 222                                                                                                          
 223     /** The different states that Launcher can be in. */                                                 
 224     private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };;               
 225     private State mState = State.WORKSPACE;                                                              
 226     private AnimatorSet mStateAnimation;                                                                 
 227                                                                                                          
 228     private boolean mIsSafeModeEnabled;                                                                  
 229                                                                                                          
 230     static final int APPWIDGET_HOST_ID = 1024;                                                           
 231     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 232     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 233     private static final int ACTIVITY_START_DELAY = 1000;                                                
 234                                                                                                          
 235     private static final Object sLock = new Object();                                                    
 236     private static int sScreen = DEFAULT_SCREEN;                                                         
 237                                                                                                          
 238     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 239     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 240                                                                                                          
 241     // How long to wait before the new-shortcut animation automatically pans the workspace               
 242     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 243     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 244     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 245     private static final int SINGLE_FRAME_DELAY = 16;                                                    
 246                                                                                                          
 247     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 248             = new CloseSystemDialogsIntentReceiver();                                                    
 249     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 250                                                                                                          
 251     private LayoutInflater mInflater;                                                                    
 252                                                                                                          
 253     private Workspace mWorkspace;                                                                        
 254     private View mLauncherView;                                                                          
 255     private View mPageIndicators;                                                                        
 256     private DragLayer mDragLayer;                                                                        
 257     private DragController mDragController;                                                              
 258     private View mWeightWatcher;                                                                         
 259                                                                                                          
 260     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 261     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 262                                                                                                          
 263     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 264     private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                 
 265     private int mPendingAddWidgetId = -1;                                                                
 266                                                                                                          
 267     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 268                                                                                                          
 269     private FolderInfo mFolderInfo;                                                                      
 270                                                                                                          
 271     private Hotseat mHotseat;                                                                            
 272     private ViewGroup mOverviewPanel;                                                                    
 273                                                                                                          
 274     private View mAllAppsButton;                                                                         
 275                                                                                                          
 276     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 277     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 278     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 279     private boolean mAutoAdvanceRunning = false;                                                         
 280     private View mQsb;                                                                                   
 281                                                                                                          
 282     private Bundle mSavedState;                                                                          
 283     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 284     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 285     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 286     private State mOnResumeState = State.NONE;                                                           
 287                                                                                                          
 288     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 289                                                                                                          
 290     private boolean mWorkspaceLoading = true;                                                            
 291                                                                                                          
 292     private boolean mPaused = true;                                                                      
 293     private boolean mRestoring;                                                                          
 294     private boolean mWaitingForResult;                                                                   
 295     private boolean mOnResumeNeedsLoad;                                                                  
 296                                                                                                          
 297     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 298     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 299                                                                                                          
 300     private Bundle mSavedInstanceState;                                                                  
 301                                                                                                          
 302     private LauncherModel mModel;                                                                        
 303     private IconCache mIconCache;                                                                        
 304     private boolean mUserPresent = true;                                                                 
 305     private boolean mVisible = false;                                                                    
 306     private boolean mHasFocus = false;                                                                   
 307     private boolean mAttached = false;                                                                   
 308                                                                                                          
 309     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 310                                                                                                          
 311     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 312                                                                                                          
 313     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 314                                                                                                          
 315     // Related to the auto-advancing of widgets                                                          
 316     private final int ADVANCE_MSG = 1;                                                                   
 317     private final int mAdvanceInterval = 20000;                                                          
 318     private final int mAdvanceStagger = 250;                                                             
 319     private long mAutoAdvanceSentTime;                                                                   
 320     private long mAutoAdvanceTimeLeft = -1;                                                              
 321     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                     
 322         new HashMap<View, AppWidgetProviderInfo>();                                                      
 323                                                                                                          
 324     // Determines how long to wait after a rotation before restoring the screen orientation to           
 325     // match the sensor state.                                                                           
 326     private final int mRestoreScreenOrientationDelay = 500;                                              
 327                                                                                                          
 328     // External icons saved in case of resource changes, orientation, etc.                               
 329     private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];           
 330     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];            
 331                                                                                                          
 332     private Drawable mWorkspaceBackgroundDrawable;                                                       
 333                                                                                                          
 334     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 335     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 336                                                                                                          
 337     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 338     static Date sDateStamp = new Date();                                                                 
 339     static DateFormat sDateFormat =                                                                      
 340             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 341     static long sRunStart = System.currentTimeMillis();                                                  
 342     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 343                                                                                                          
 344     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 345     // it from the context.                                                                              
 346     private SharedPreferences mSharedPrefs;                                                              
 347                                                                                                          
 348     private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                   
 349                                                                                                          
 350     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 351     // when we scroll to that page on resume.                                                            
 352     private ImageView mFolderIconImageView;                                                              
 353     private Bitmap mFolderIconBitmap;                                                                    
 354     private Canvas mFolderIconCanvas;                                                                    
 355     private Rect mRectForFolderAnimation = new Rect();                                                   
 356                                                                                                          
 357     private BubbleTextView mWaitingForResume;                                                            
 358                                                                                                          
 359     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 360         public void run() {                                                                              
 361             if (mWorkspace != null) {                                                                    
 362                 mWorkspace.buildPageHardwareLayers();                                                    
 363             }                                                                                            
 364         }                                                                                                
 365     };                                                                                                   
 366                                                                                                          
 367     private static PendingAddArguments sPendingAddItem;                                                  
 368                                                                                                          
 369     public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);      
 370                                                                                                          
 371     private static class PendingAddArguments {                                                           
 372         int requestCode;                                                                                 
 373         Intent intent;                                                                                   
 374         long container;                                                                                  
 375         long screenId;                                                                                   
 376         int cellX;                                                                                       
 377         int cellY;                                                                                       
 378         int appWidgetId;                                                                                 
 379     }                                                                                                    
 380                                                                                                          
 381     private Stats mStats;                                                                                
 382                                                                                                          
 383     FocusIndicatorView mFocusHandler;                                                                    
 384                                                                                                          
 385     static boolean isPropertyEnabled(String propertyName) {                                              
 386         return Log.isLoggable(propertyName, Log.VERBOSE);                                                
 387     }                                                                                                    
 388                                                                                                          
 389     @Override                                                                                            
 390     protected void onCreate(Bundle savedInstanceState) {                                                 
 391         if (DEBUG_STRICT_MODE) {                                                                         
 392             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 393                     .detectDiskReads()                                                                   
 394                     .detectDiskWrites()                                                                  
 395                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 396                     .penaltyLog()                                                                        
 397                     .build());                                                                           
 398             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 399                     .detectLeakedSqlLiteObjects()                                                        
 400                     .detectLeakedClosableObjects()                                                       
 401                     .penaltyLog()                                                                        
 402                     .penaltyDeath()                                                                      
 403                     .build());                                                                           
 404         }                                                                                                
 405                                                                                                          
 406         super.onCreate(savedInstanceState);                                                              
 407                                                                                                          
 408         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 409         LauncherAppState app = LauncherAppState.getInstance();                                           
 410         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 411         // Determine the dynamic grid properties                                                         
 412         Point smallestSize = new Point();                                                                
 413         Point largestSize = new Point();                                                                 
 414         Point realSize = new Point();                                                                    
 415         Display display = getWindowManager().getDefaultDisplay();                                        
 416         display.getCurrentSizeRange(smallestSize, largestSize);                                          
 417         display.getRealSize(realSize);                                                                   
 418         DisplayMetrics dm = new DisplayMetrics();                                                        
 419         display.getMetrics(dm);                                                                          
 420                                                                                                          
 421         // Lazy-initialize the dynamic grid                                                              
 422         DeviceProfile grid = app.initDynamicGrid(this,                                                   
 423                 Math.min(smallestSize.x, smallestSize.y),                                                
 424                 Math.min(largestSize.x, largestSize.y),                                                  
 425                 realSize.x, realSize.y,                                                                  
 426                 dm.widthPixels, dm.heightPixels);                                                        
 427                                                                                                          
 428         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 429         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 430                 Context.MODE_PRIVATE);                                                                   
 431         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 432         mModel = app.setLauncher(this);                                                                  
 433         mIconCache = app.getIconCache();                                                                 
 434         mIconCache.flushInvalidIcons(grid);                                                              
 435         mDragController = new DragController(this);                                                      
 436         mInflater = getLayoutInflater();                                                                 
 437                                                                                                          
 438         mStats = new Stats(this);                                                                        
 439                                                                                                          
 440         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 441                                                                                                          
 442         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 443         mAppWidgetHost.startListening();                                                                 
 444                                                                                                          
 445         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 446         // this also ensures that any synchronous binding below doesn't re-trigger another               
 447         // LauncherModel load.                                                                           
 448         mPaused = false;                                                                                 
 449                                                                                                          
 450         if (PROFILE_STARTUP) {                                                                           
 451             android.os.Debug.startMethodTracing(                                                         
 452                     Environment.getExternalStorageDirectory() + "/launcher");                            
 453         }                                                                                                
 454                                                                                                          
 455         checkForLocaleChange();                                                                          
 456         setContentView(R.layout.launcher);                                                               
 457                                                                                                          
 458         setupViews();                                                                                    
 459         grid.layout(this);                                                                               
 460                                                                                                          
 461         registerContentObservers();                                                                      
 462                                                                                                          
 463         lockAllApps();                                                                                   
 464                                                                                                          
 465         mSavedState = savedInstanceState;                                                                
 466         restoreState(mSavedState);                                                                       
 467                                                                                                          
 468         if (PROFILE_STARTUP) {                                                                           
 469             android.os.Debug.stopMethodTracing();                                                        
 470         }                                                                                                
 471                                                                                                          
 472         if (!mRestoring) {                                                                               
 473             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 474                 // If the user leaves launcher, then we should just load items asynchronously when       
 475                 // they return.                                                                          
 476                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 477             } else {                                                                                     
 478                 // We only load the page synchronously if the user rotates (or triggers a                
 479                 // configuration change) while launcher is in the foreground                             
 480                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 481             }                                                                                            
 482         }                                                                                                
 483                                                                                                          
 484         // For handling default keys                                                                     
 485         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 486         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 487                                                                                                          
 488         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 489         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 490                                                                                                          
 491         updateGlobalIcons();                                                                             
 492                                                                                                          
 493         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 494         unlockScreenOrientation(true);                                                                   
 495                                                                                                          
 496         if (shouldShowIntroScreen()) {                                                                   
 497             showIntroScreen();                                                                           
 498         } else {                                                                                         
 499             showFirstRunActivity();                                                                      
 500             showFirstRunClings();                                                                        
 501         }                                                                                                
 502     }                                                                                                    
 503                                                                                                          
 504     @Override                                                                                            
 505     public void onLauncherProviderChange() { }                                                           
 506                                                                                                          
 507     /** To be overriden by subclasses to hint to Launcher that we have custom content */                 
 508     protected boolean hasCustomContentToLeft() {                                                         
 509         return false;                                                                                    
 510     }                                                                                                    
 511                                                                                                          
 512     /**                                                                                                  
 513      * To be overridden by subclasses to populate the custom content container and call                  
 514      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 515      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 516      */                                                                                                  
 517     protected void populateCustomContentContainer() {                                                    
 518     }                                                                                                    
 519                                                                                                          
 520     /**                                                                                                  
 521      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 522      * ensure the custom content page is added or removed if necessary.                                  
 523      */                                                                                                  
 524     protected void invalidateHasCustomContentToLeft() {                                                  
 525         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 526             // Not bound yet, wait for bindScreens to be called.                                         
 527             return;                                                                                      
 528         }                                                                                                
 529                                                                                                          
 530         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 531             // Create the custom content page and call the subclass to populate it.                      
 532             mWorkspace.createCustomContentContainer();                                                   
 533             populateCustomContentContainer();                                                            
 534         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 535             mWorkspace.removeCustomContentPage();                                                        
 536         }                                                                                                
 537     }                                                                                                    
 538                                                                                                          
 539     private void updateGlobalIcons() {                                                                   
 540         boolean searchVisible = false;                                                                   
 541         boolean voiceVisible = false;                                                                    
 542         // If we have a saved version of these external icons, we load them up immediately               
 543         int coi = getCurrentOrientationIndexForGlobalIcons();                                            
 544         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                           
 545             searchVisible = updateGlobalSearchIcon();                                                    
 546             voiceVisible = updateVoiceSearchIcon(searchVisible);                                         
 547         }                                                                                                
 548         if (sGlobalSearchIcon[coi] != null) {                                                            
 549              updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                             
 550              searchVisible = true;                                                                       
 551         }                                                                                                
 552         if (sVoiceSearchIcon[coi] != null) {                                                             
 553             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                
 554             voiceVisible = true;                                                                         
 555         }                                                                                                
 556         if (mSearchDropTargetBar != null) {                                                              
 557             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
 558         }                                                                                                
 559     }                                                                                                    
 560                                                                                                          
 561     private void checkForLocaleChange() {                                                                
 562         if (sLocaleConfiguration == null) {                                                              
 563             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 564                 @Override                                                                                
 565                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 566                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 567                     readConfiguration(Launcher.this, localeConfiguration);                               
 568                     return localeConfiguration;                                                          
 569                 }                                                                                        
 570                                                                                                          
 571                 @Override                                                                                
 572                 protected void onPostExecute(LocaleConfiguration result) {                               
 573                     sLocaleConfiguration = result;                                                       
 574                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 575                 }                                                                                        
 576             }.execute();                                                                                 
 577             return;                                                                                      
 578         }                                                                                                
 579                                                                                                          
 580         final Configuration configuration = getResources().getConfiguration();                           
 581                                                                                                          
 582         final String previousLocale = sLocaleConfiguration.locale;                                       
 583         final String locale = configuration.locale.toString();                                           
 584                                                                                                          
 585         final int previousMcc = sLocaleConfiguration.mcc;                                                
 586         final int mcc = configuration.mcc;                                                               
 587                                                                                                          
 588         final int previousMnc = sLocaleConfiguration.mnc;                                                
 589         final int mnc = configuration.mnc;                                                               
 590                                                                                                          
 591         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 592                                                                                                          
 593         if (localeChanged) {                                                                             
 594             sLocaleConfiguration.locale = locale;                                                        
 595             sLocaleConfiguration.mcc = mcc;                                                              
 596             sLocaleConfiguration.mnc = mnc;                                                              
 597                                                                                                          
 598             mIconCache.flush();                                                                          
 599                                                                                                          
 600             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 601             new AsyncTask<Void, Void, Void>() {                                                          
 602                 public Void doInBackground(Void ... args) {                                              
 603                     writeConfiguration(Launcher.this, localeConfiguration);                              
 604                     return null;                                                                         
 605                 }                                                                                        
 606             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 607         }                                                                                                
 608     }                                                                                                    
 609                                                                                                          
 610     private static class LocaleConfiguration {                                                           
 611         public String locale;                                                                            
 612         public int mcc = -1;                                                                             
 613         public int mnc = -1;                                                                             
 614     }                                                                                                    
 615                                                                                                          
 616     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 617         DataInputStream in = null;                                                                       
 618         try {                                                                                            
 619             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFS));               
 620             configuration.locale = in.readUTF();                                                         
 621             configuration.mcc = in.readInt();                                                            
 622             configuration.mnc = in.readInt();                                                            
 623         } catch (FileNotFoundException e) {                                                              
 624             // Ignore                                                                                    
 625         } catch (IOException e) {                                                                        
 626             // Ignore                                                                                    
 627         } finally {                                                                                      
 628             if (in != null) {                                                                            
 629                 try {                                                                                    
 630                     in.close();                                                                          
 631                 } catch (IOException e) {                                                                
 632                     // Ignore                                                                            
 633                 }                                                                                        
 634             }                                                                                            
 635         }                                                                                                
 636     }                                                                                                    
 637                                                                                                          
 638     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 639         DataOutputStream out = null;                                                                     
 640         try {                                                                                            
 641             out = new DataOutputStream(context.openFileOutput(                                           
 642                     LauncherFiles.LAUNCHER_PREFS, MODE_PRIVATE));                                        
 643             out.writeUTF(configuration.locale);                                                          
 644             out.writeInt(configuration.mcc);                                                             
 645             out.writeInt(configuration.mnc);                                                             
 646             out.flush();                                                                                 
 647         } catch (FileNotFoundException e) {                                                              
 648             // Ignore                                                                                    
 649         } catch (IOException e) {                                                                        
 650             //noinspection ResultOfMethodCallIgnored                                                     
 651             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFS).delete();                            
 652         } finally {                                                                                      
 653             if (out != null) {                                                                           
 654                 try {                                                                                    
 655                     out.close();                                                                         
 656                 } catch (IOException e) {                                                                
 657                     // Ignore                                                                            
 658                 }                                                                                        
 659             }                                                                                            
 660         }                                                                                                
 661     }                                                                                                    
 662                                                                                                          
 663     public Stats getStats() {                                                                            
 664         return mStats;                                                                                   
 665     }                                                                                                    
 666                                                                                                          
 667     public LayoutInflater getInflater() {                                                                
 668         return mInflater;                                                                                
 669     }                                                                                                    
 670                                                                                                          
 671     boolean isDraggingEnabled() {                                                                        
 672         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 673         // that is subsequently removed from the workspace in startBinding().                            
 674         return !mModel.isLoadingWorkspace();                                                             
 675     }                                                                                                    
 676                                                                                                          
 677     static int getScreen() {                                                                             
 678         synchronized (sLock) {                                                                           
 679             return sScreen;                                                                              
 680         }                                                                                                
 681     }                                                                                                    
 682                                                                                                          
 683     static void setScreen(int screen) {                                                                  
 684         synchronized (sLock) {                                                                           
 685             sScreen = screen;                                                                            
 686         }                                                                                                
 687     }                                                                                                    
 688                                                                                                          
 689     public static int generateViewId() {                                                                 
 690         if (Build.VERSION.SDK_INT >= 17) {                                                               
 691             return View.generateViewId();                                                                
 692         } else {                                                                                         
 693             // View.generateViewId() is not available. The following fallback logic is a copy            
 694             // of its implementation.                                                                    
 695             for (;;) {                                                                                   
 696                 final int result = sNextGeneratedId.get();                                               
 697                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 698                 int newValue = result + 1;                                                               
 699                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 700                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 701                     return result;                                                                       
 702                 }                                                                                        
 703             }                                                                                            
 704         }                                                                                                
 705     }                                                                                                    
 706                                                                                                          
 707     public int getViewIdForItem(ItemInfo info) {                                                         
 708         // This cast is safe given the > 2B range for int.                                               
 709         int itemId = (int) info.id;                                                                      
 710         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 711             return mItemIdToViewId.get(itemId);                                                          
 712         }                                                                                                
 713         int viewId = generateViewId();                                                                   
 714         mItemIdToViewId.put(itemId, viewId);                                                             
 715         return viewId;                                                                                   
 716     }                                                                                                    
 717                                                                                                          
 718     /**                                                                                                  
 719      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 720      * a configuration step, this allows the proper animations to run after other transitions.           
 721      */                                                                                                  
 722     private long completeAdd(PendingAddArguments args) {                                                 
 723         long screenId = args.screenId;                                                                   
 724         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 725             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 726             // that the drop page actually exists.                                                       
 727             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 728         }                                                                                                
 729                                                                                                          
 730         switch (args.requestCode) {                                                                      
 731             case REQUEST_CREATE_SHORTCUT:                                                                
 732                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 733                         args.cellY);                                                                     
 734                 break;                                                                                   
 735             case REQUEST_CREATE_APPWIDGET:                                                               
 736                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 737                 break;                                                                                   
 738             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 739                 completeRestoreAppWidget(args.appWidgetId);                                              
 740                 break;                                                                                   
 741         }                                                                                                
 742         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 743         // if you turned the screen off and then back while in All Apps, Launcher would not              
 744         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 745         resetAddInfo();                                                                                  
 746         return screenId;                                                                                 
 747     }                                                                                                    
 748                                                                                                          
 749     @Override                                                                                            
 750     protected void onActivityResult(                                                                     
 751             final int requestCode, final int resultCode, final Intent data) {                            
 752         // Reset the startActivity waiting flag                                                          
 753         setWaitingForResult(false);                                                                      
 754         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 755         mPendingAddWidgetId = -1;                                                                        
 756                                                                                                          
 757         Runnable exitSpringLoaded = new Runnable() {                                                     
 758             @Override                                                                                    
 759             public void run() {                                                                          
 760                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 761                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 762             }                                                                                            
 763         };                                                                                               
 764                                                                                                          
 765         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 766             final int appWidgetId = data != null ?                                                       
 767                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 768             if (resultCode == RESULT_CANCELED) {                                                         
 769                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 770                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 771                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 772             } else if (resultCode == RESULT_OK) {                                                        
 773                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 774                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 775             }                                                                                            
 776             return;                                                                                      
 777         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 778             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 779                 mWorkspace.exitOverviewMode(false);                                                      
 780             }                                                                                            
 781             return;                                                                                      
 782         }                                                                                                
 783                                                                                                          
 784         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 785                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 786                                                                                                          
 787         final boolean workspaceLocked = isWorkspaceLocked();                                             
 788         // We have special handling for widgets                                                          
 789         if (isWidgetDrop) {                                                                              
 790             final int appWidgetId;                                                                       
 791             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 792                     : -1;                                                                                
 793             if (widgetId < 0) {                                                                          
 794                 appWidgetId = pendingAddWidgetId;                                                        
 795             } else {                                                                                     
 796                 appWidgetId = widgetId;                                                                  
 797             }                                                                                            
 798                                                                                                          
 799             final int result;                                                                            
 800             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 801                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 802                         "returned from the widget configuration activity.");                             
 803                 result = RESULT_CANCELED;                                                                
 804                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 805                 final Runnable onComplete = new Runnable() {                                             
 806                     @Override                                                                            
 807                     public void run() {                                                                  
 808                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 809                     }                                                                                    
 810                 };                                                                                       
 811                 if (workspaceLocked) {                                                                   
 812                     // No need to remove the empty screen if we're mid-binding, as the                   
 813                     // the bind will not add the empty screen.                                           
 814                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 815                 } else {                                                                                 
 816                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 817                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 818                 }                                                                                        
 819             } else {                                                                                     
 820                 if (!workspaceLocked) {                                                                  
 821                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 822                         // When the screen id represents an actual screen (as opposed to a rank)         
 823                         // we make sure that the drop page actually exists.                              
 824                         mPendingAddInfo.screenId =                                                       
 825                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 826                     }                                                                                    
 827                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 828                                                                                                          
 829                     dropLayout.setDropPending(true);                                                     
 830                     final Runnable onComplete = new Runnable() {                                         
 831                         @Override                                                                        
 832                         public void run() {                                                              
 833                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 834                             dropLayout.setDropPending(false);                                            
 835                         }                                                                                
 836                     };                                                                                   
 837                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 838                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 839                 } else {                                                                                 
 840                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 841                             mPendingAddInfo);                                                            
 842                     sPendingAddItem = args;                                                              
 843                 }                                                                                        
 844             }                                                                                            
 845             return;                                                                                      
 846         }                                                                                                
 847                                                                                                          
 848         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 849             if (resultCode == RESULT_OK) {                                                               
 850                 // Update the widget view.                                                               
 851                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 852                         pendingAddWidgetId, mPendingAddInfo);                                            
 853                 if (workspaceLocked) {                                                                   
 854                     sPendingAddItem = args;                                                              
 855                 } else {                                                                                 
 856                     completeAdd(args);                                                                   
 857                 }                                                                                        
 858             }                                                                                            
 859             // Leave the widget in the pending state if the user canceled the configure.                 
 860             return;                                                                                      
 861         }                                                                                                
 862                                                                                                          
 863         // The pattern used here is that a user PICKs a specific application,                            
 864         // which, depending on the target, might need to CREATE the actual target.                       
 865                                                                                                          
 866         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 867         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 868         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 869             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 870                     mPendingAddInfo);                                                                    
 871             if (isWorkspaceLocked()) {                                                                   
 872                 sPendingAddItem = args;                                                                  
 873             } else {                                                                                     
 874                 completeAdd(args);                                                                       
 875                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 876                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 877             }                                                                                            
 878         } else if (resultCode == RESULT_CANCELED) {                                                      
 879             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 880                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 881         }                                                                                                
 882         mDragLayer.clearAnimatedView();                                                                  
 883     }                                                                                                    
 884                                                                                                          
 885     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 886             appWidgetId, ItemInfo info) {                                                                
 887         PendingAddArguments args = new PendingAddArguments();                                            
 888         args.requestCode = requestCode;                                                                  
 889         args.intent = data;                                                                              
 890         args.container = info.container;                                                                 
 891         args.screenId = info.screenId;                                                                   
 892         args.cellX = info.cellX;                                                                         
 893         args.cellY = info.cellY;                                                                         
 894         args.appWidgetId = appWidgetId;                                                                  
 895         return args;                                                                                     
 896     }                                                                                                    
 897                                                                                                          
 898     /**                                                                                                  
 899      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 900      *                                                                                                   
 901      * @param screenId the screen id to check                                                            
 902      * @return the new screen, or screenId if it exists                                                  
 903      */                                                                                                  
 904     private long ensurePendingDropLayoutExists(long screenId) {                                          
 905         CellLayout dropLayout =                                                                          
 906                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 907         if (dropLayout == null) {                                                                        
 908             // it's possible that the add screen was removed because it was                              
 909             // empty and a re-bind occurred                                                              
 910             mWorkspace.addExtraEmptyScreen();                                                            
 911             return mWorkspace.commitExtraEmptyScreen();                                                  
 912         } else {                                                                                         
 913             return screenId;                                                                             
 914         }                                                                                                
 915     }                                                                                                    
 916                                                                                                          
 917     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 918         CellLayout cellLayout =                                                                          
 919                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 920         Runnable onCompleteRunnable = null;                                                              
 921         int animationType = 0;                                                                           
 922                                                                                                          
 923         AppWidgetHostView boundWidget = null;                                                            
 924         if (resultCode == RESULT_OK) {                                                                   
 925             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 926             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 927                     mPendingAddWidgetInfo);                                                              
 928             boundWidget = layout;                                                                        
 929             onCompleteRunnable = new Runnable() {                                                        
 930                 @Override                                                                                
 931                 public void run() {                                                                      
 932                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 933                             mPendingAddInfo.screenId, layout, null);                                     
 934                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 935                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 936                 }                                                                                        
 937             };                                                                                           
 938         } else if (resultCode == RESULT_CANCELED) {                                                      
 939             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 940             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 941         }                                                                                                
 942         if (mDragLayer.getAnimatedView() != null) {                                                      
 943             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 944                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 945                     animationType, boundWidget, true);                                                   
 946         } else if (onCompleteRunnable != null) {                                                         
 947             // The animated view may be null in the case of a rotation during widget configuration       
 948             onCompleteRunnable.run();                                                                    
 949         }                                                                                                
 950     }                                                                                                    
 951                                                                                                          
 952     @Override                                                                                            
 953     protected void onStop() {                                                                            
 954         super.onStop();                                                                                  
 955         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 956     }                                                                                                    
 957                                                                                                          
 958     @Override                                                                                            
 959     protected void onStart() {                                                                           
 960         super.onStart();                                                                                 
 961         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 962     }                                                                                                    
 963                                                                                                          
 964     @Override                                                                                            
 965     protected void onResume() {                                                                          
 966         long startTime = 0;                                                                              
 967         if (DEBUG_RESUME_TIME) {                                                                         
 968             startTime = System.currentTimeMillis();                                                      
 969             Log.v(TAG, "Launcher.onResume()");                                                           
 970         }                                                                                                
 971         super.onResume();                                                                                
 972                                                                                                          
 973         // Restore the previous launcher state                                                           
 974         if (mOnResumeState == State.WORKSPACE) {                                                         
 975             showWorkspace(false);                                                                        
 976         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                             
 977             showAllApps(false, mAppsCustomizeContent.getContentType(), false);                           
 978         }                                                                                                
 979         mOnResumeState = State.NONE;                                                                     
 980                                                                                                          
 981         // Background was set to gradient in onPause(), restore to black if in all apps.                 
 982         setWorkspaceBackground(mState == State.WORKSPACE);                                               
 983                                                                                                          
 984         mPaused = false;                                                                                 
 985         if (mRestoring || mOnResumeNeedsLoad) {                                                          
 986             setWorkspaceLoading(true);                                                                   
 987             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
 988             mRestoring = false;                                                                          
 989             mOnResumeNeedsLoad = false;                                                                  
 990         }                                                                                                
 991         if (mBindOnResumeCallbacks.size() > 0) {                                                         
 992             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
 993             // execute them here                                                                         
 994             long startTimeCallbacks = 0;                                                                 
 995             if (DEBUG_RESUME_TIME) {                                                                     
 996                 startTimeCallbacks = System.currentTimeMillis();                                         
 997             }                                                                                            
 998                                                                                                          
 999             if (mAppsCustomizeContent != null) {                                                         
1000                 mAppsCustomizeContent.setBulkBind(true);                                                 
1001             }                                                                                            
1002             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1003                 mBindOnResumeCallbacks.get(i).run();                                                     
1004             }                                                                                            
1005             if (mAppsCustomizeContent != null) {                                                         
1006                 mAppsCustomizeContent.setBulkBind(false);                                                
1007             }                                                                                            
1008             mBindOnResumeCallbacks.clear();                                                              
1009             if (DEBUG_RESUME_TIME) {                                                                     
1010                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1011                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1012             }                                                                                            
1013         }                                                                                                
1014         if (mOnResumeCallbacks.size() > 0) {                                                             
1015             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1016                 mOnResumeCallbacks.get(i).run();                                                         
1017             }                                                                                            
1018             mOnResumeCallbacks.clear();                                                                  
1019         }                                                                                                
1020                                                                                                          
1021         // Reset the pressed state of icons that were locked in the press state while activities         
1022         // were launching                                                                                
1023         if (mWaitingForResume != null) {                                                                 
1024             // Resets the previous workspace icon press state                                            
1025             mWaitingForResume.setStayPressed(false);                                                     
1026         }                                                                                                
1027                                                                                                          
1028         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1029         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1030         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1031         // orientation.                                                                                  
1032         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1033                                                                                                          
1034         // Process any items that were added while Launcher was away.                                    
1035         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1036                                                                                                          
1037         // Update the voice search button proxy                                                          
1038         updateVoiceButtonProxyVisible(false);                                                            
1039                                                                                                          
1040         // Again, as with the above scenario, it's possible that one or more of the global icons         
1041         // were updated in the wrong orientation.                                                        
1042         updateGlobalIcons();                                                                             
1043         if (DEBUG_RESUME_TIME) {                                                                         
1044             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1045         }                                                                                                
1046                                                                                                          
1047         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1048             // If we are resuming and the custom content is the current page, we call onShow().          
1049             // It is also poassible that onShow will instead be called slightly after first layout       
1050             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1051             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1052                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1053             }                                                                                            
1054         }                                                                                                
1055         mWorkspace.updateInteractionForState();                                                          
1056         mWorkspace.onResume();                                                                           
1057                                                                                                          
1058         PackageInstallerCompat.getInstance(this).onResume();                                             
1059     }                                                                                                    
1060                                                                                                          
1061     @Override                                                                                            
1062     protected void onPause() {                                                                           
1063         // Ensure that items added to Launcher are queued until Launcher returns                         
1064         InstallShortcutReceiver.enableInstallQueue();                                                    
1065         PackageInstallerCompat.getInstance(this).onPause();                                              
1066                                                                                                          
1067         super.onPause();                                                                                 
1068         mPaused = true;                                                                                  
1069         mDragController.cancelDrag();                                                                    
1070         mDragController.resetLastGestureUpTime();                                                        
1071                                                                                                          
1072         // We call onHide() aggressively. The custom content callbacks should be able to                 
1073         // debounce excess onHide calls.                                                                 
1074         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1075             mWorkspace.getCustomContentCallbacks().onHide();                                             
1076         }                                                                                                
1077     }                                                                                                    
1078                                                                                                          
1079     QSBScroller mQsbScroller = new QSBScroller() {                                                       
1080         int scrollY = 0;                                                                                 
1081                                                                                                          
1082         @Override                                                                                        
1083         public void setScrollY(int scroll) {                                                             
1084             scrollY = scroll;                                                                            
1085                                                                                                          
1086             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1087                 mSearchDropTargetBar.setTranslationY(- scrollY);                                         
1088                 getQsbBar().setTranslationY(-scrollY);                                                   
1089             }                                                                                            
1090         }                                                                                                
1091     };                                                                                                   
1092                                                                                                          
1093     public void resetQSBScroll() {                                                                       
1094         mSearchDropTargetBar.animate().translationY(0).start();                                          
1095         getQsbBar().animate().translationY(0).start();                                                   
1096     }                                                                                                    
1097                                                                                                          
1098     public interface CustomContentCallbacks {                                                            
1099         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1100         // by a onResume or by scrolling otherwise.                                                      
1101         public void onShow(boolean fromResume);                                                          
1102                                                                                                          
1103         // Custom content is completely hidden                                                           
1104         public void onHide();                                                                            
1105                                                                                                          
1106         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1107         public void onScrollProgressChanged(float progress);                                             
1108                                                                                                          
1109         // Indicates whether the user is allowed to scroll away from the custom content.                 
1110         boolean isScrollingAllowed();                                                                    
1111     }                                                                                                    
1112                                                                                                          
1113     protected boolean hasSettings() {                                                                    
1114         return false;                                                                                    
1115     }                                                                                                    
1116                                                                                                          
1117     public interface QSBScroller {                                                                       
1118         public void setScrollY(int scrollY);                                                             
1119     }                                                                                                    
1120                                                                                                          
1121     public QSBScroller addToCustomContentPage(View customContent,                                        
1122             CustomContentCallbacks callbacks, String description) {                                      
1123         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1124         return mQsbScroller;                                                                             
1125     }                                                                                                    
1126                                                                                                          
1127     // The custom content needs to offset its content to account for the QSB                             
1128     public int getTopOffsetForCustomContent() {                                                          
1129         return mWorkspace.getPaddingTop();                                                               
1130     }                                                                                                    
1131                                                                                                          
1132     @Override                                                                                            
1133     public Object onRetainNonConfigurationInstance() {                                                   
1134         // Flag the loader to stop early before switching                                                
1135         if (mModel.isCurrentCallbacks(this)) {                                                           
1136             mModel.stopLoader();                                                                         
1137         }                                                                                                
1138         if (mAppsCustomizeContent != null) {                                                             
1139             mAppsCustomizeContent.surrender();                                                           
1140         }                                                                                                
1141         return Boolean.TRUE;                                                                             
1142     }                                                                                                    
1143                                                                                                          
1144     // We can't hide the IME if it was forced open.  So don't bother                                     
1145     @Override                                                                                            
1146     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1147         super.onWindowFocusChanged(hasFocus);                                                            
1148         mHasFocus = hasFocus;                                                                            
1149     }                                                                                                    
1150                                                                                                          
1151     private boolean acceptFilter() {                                                                     
1152         final InputMethodManager inputManager = (InputMethodManager)                                     
1153                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1154         return !inputManager.isFullscreenMode();                                                         
1155     }                                                                                                    
1156                                                                                                          
1157     @Override                                                                                            
1158     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1159         final int uniChar = event.getUnicodeChar();                                                      
1160         final boolean handled = super.onKeyDown(keyCode, event);                                         
1161         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1162         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1163             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1164                     keyCode, event);                                                                     
1165             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1166                 // something usable has been typed - start a search                                      
1167                 // the typed text will be retrieved and cleared by                                       
1168                 // showSearchDialog()                                                                    
1169                 // If there are multiple keystrokes before the search dialog takes focus,                
1170                 // onSearchRequested() will be called for every keystroke,                               
1171                 // but it is idempotent, so it's fine.                                                   
1172                 return onSearchRequested();                                                              
1173             }                                                                                            
1174         }                                                                                                
1175                                                                                                          
1176         // Eat the long press event so the keyboard doesn't come up.                                     
1177         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1178             return true;                                                                                 
1179         }                                                                                                
1180                                                                                                          
1181         return handled;                                                                                  
1182     }                                                                                                    
1183                                                                                                          
1184     private String getTypedText() {                                                                      
1185         return mDefaultKeySsb.toString();                                                                
1186     }                                                                                                    
1187                                                                                                          
1188     private void clearTypedText() {                                                                      
1189         mDefaultKeySsb.clear();                                                                          
1190         mDefaultKeySsb.clearSpans();                                                                     
1191         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1192     }                                                                                                    
1193                                                                                                          
1194     /**                                                                                                  
1195      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1196      * State                                                                                             
1197      */                                                                                                  
1198     private static State intToState(int stateOrdinal) {                                                  
1199         State state = State.WORKSPACE;                                                                   
1200         final State[] stateValues = State.values();                                                      
1201         for (int i = 0; i < stateValues.length; i++) {                                                   
1202             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1203                 state = stateValues[i];                                                                  
1204                 break;                                                                                   
1205             }                                                                                            
1206         }                                                                                                
1207         return state;                                                                                    
1208     }                                                                                                    
1209                                                                                                          
1210     /**                                                                                                  
1211      * Restores the previous state, if it exists.                                                        
1212      *                                                                                                   
1213      * @param savedState The previous state.                                                             
1214      */                                                                                                  
1215     @SuppressWarnings("unchecked")                                                                       
1216     private void restoreState(Bundle savedState) {                                                       
1217         if (savedState == null) {                                                                        
1218             return;                                                                                      
1219         }                                                                                                
1220                                                                                                          
1221         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1222         if (state == State.APPS_CUSTOMIZE) {                                                             
1223             mOnResumeState = State.APPS_CUSTOMIZE;                                                       
1224         }                                                                                                
1225                                                                                                          
1226         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1227                 PagedView.INVALID_RESTORE_PAGE);                                                         
1228         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1229             mWorkspace.setRestorePage(currentScreen);                                                    
1230         }                                                                                                
1231                                                                                                          
1232         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1233         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1234                                                                                                          
1235         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1236             mPendingAddInfo.container = pendingAddContainer;                                             
1237             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1238             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1239             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1240             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1241             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1242             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1243             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1244             setWaitingForResult(true);                                                                   
1245             mRestoring = true;                                                                           
1246         }                                                                                                
1247                                                                                                          
1248         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1249         if (renameFolder) {                                                                              
1250             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1251             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1252             mRestoring = true;                                                                           
1253         }                                                                                                
1254                                                                                                          
1255         // Restore the AppsCustomize tab                                                                 
1256         if (mAppsCustomizeTabHost != null) {                                                             
1257             String curTab = savedState.getString("apps_customize_currentTab");                           
1258             if (curTab != null) {                                                                        
1259                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1260                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1261                 mAppsCustomizeContent.loadAssociatedPages(                                               
1262                         mAppsCustomizeContent.getCurrentPage());                                         
1263             }                                                                                            
1264                                                                                                          
1265             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1266             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1267         }                                                                                                
1268         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1269                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1270     }                                                                                                    
1271                                                                                                          
1272     /**                                                                                                  
1273      * Finds all the views we need and configure them properly.                                          
1274      */                                                                                                  
1275     private void setupViews() {                                                                          
1276         final DragController dragController = mDragController;                                           
1277                                                                                                          
1278         mLauncherView = findViewById(R.id.launcher);                                                     
1279         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1280         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1281         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1282         mWorkspace.setPageSwitchListener(this);                                                          
1283         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1284                                                                                                          
1285         mLauncherView.setSystemUiVisibility(                                                             
1286                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1287         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1288                                                                                                          
1289         // Setup the drag layer                                                                          
1290         mDragLayer.setup(this, dragController);                                                          
1291                                                                                                          
1292         // Setup the hotseat                                                                             
1293         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1294         if (mHotseat != null) {                                                                          
1295             mHotseat.setup(this);                                                                        
1296             mHotseat.setOnLongClickListener(this);                                                       
1297         }                                                                                                
1298                                                                                                          
1299         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1300         View widgetButton = findViewById(R.id.widget_button);                                            
1301         widgetButton.setOnClickListener(new OnClickListener() {                                          
1302             @Override                                                                                    
1303             public void onClick(View arg0) {                                                             
1304                 if (!mWorkspace.isSwitchingState()) {                                                    
1305                     onClickAddWidgetButton(arg0);                                                        
1306                 }                                                                                        
1307             }                                                                                            
1308         });                                                                                              
1309         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1310                                                                                                          
1311         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1312         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1313             @Override                                                                                    
1314             public void onClick(View arg0) {                                                             
1315                 if (!mWorkspace.isSwitchingState()) {                                                    
1316                     onClickWallpaperPicker(arg0);                                                        
1317                 }                                                                                        
1318             }                                                                                            
1319         });                                                                                              
1320         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1321                                                                                                          
1322         View settingsButton = findViewById(R.id.settings_button);                                        
1323         if (hasSettings()) {                                                                             
1324             settingsButton.setOnClickListener(new OnClickListener() {                                    
1325                 @Override                                                                                
1326                 public void onClick(View arg0) {                                                         
1327                     if (!mWorkspace.isSwitchingState()) {                                                
1328                         onClickSettingsButton(arg0);                                                     
1329                     }                                                                                    
1330                 }                                                                                        
1331             });                                                                                          
1332             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1333         } else {                                                                                         
1334             settingsButton.setVisibility(View.GONE);                                                     
1335             FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();     
1336             lp.gravity = Gravity.END | Gravity.TOP;                                                      
1337             widgetButton.requestLayout();                                                                
1338         }                                                                                                
1339                                                                                                          
1340         mOverviewPanel.setAlpha(0f);                                                                     
1341                                                                                                          
1342         // Setup the workspace                                                                           
1343         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1344         mWorkspace.setOnLongClickListener(this);                                                         
1345         mWorkspace.setup(dragController);                                                                
1346         dragController.addDragListener(mWorkspace);                                                      
1347                                                                                                          
1348         // Get the search/delete bar                                                                     
1349         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1350                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1351                                                                                                          
1352         // Setup AppsCustomize                                                                           
1353         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1354         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1355                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1356         mAppsCustomizeContent.setup(this, dragController);                                               
1357                                                                                                          
1358         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1359         dragController.setDragScoller(mWorkspace);                                                       
1360         dragController.setScrollView(mDragLayer);                                                        
1361         dragController.setMoveTarget(mWorkspace);                                                        
1362         dragController.addDropTarget(mWorkspace);                                                        
1363         if (mSearchDropTargetBar != null) {                                                              
1364             mSearchDropTargetBar.setup(this, dragController);                                            
1365         }                                                                                                
1366                                                                                                          
1367         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1368             Log.v(TAG, "adding WeightWatcher");                                                          
1369             mWeightWatcher = new WeightWatcher(this);                                                    
1370             mWeightWatcher.setAlpha(0.5f);                                                               
1371             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1372                     new FrameLayout.LayoutParams(                                                        
1373                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1374                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1375                             Gravity.BOTTOM)                                                              
1376             );                                                                                           
1377                                                                                                          
1378             boolean show = shouldShowWeightWatcher();                                                    
1379             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1380         }                                                                                                
1381     }                                                                                                    
1382                                                                                                          
1383     /**                                                                                                  
1384      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1385      */                                                                                                  
1386     public void setAllAppsButton(View allAppsButton) {                                                   
1387         mAllAppsButton = allAppsButton;                                                                  
1388     }                                                                                                    
1389                                                                                                          
1390     public View getAllAppsButton() {                                                                     
1391         return mAllAppsButton;                                                                           
1392     }                                                                                                    
1393                                                                                                          
1394     /**                                                                                                  
1395      * Creates a view representing a shortcut.                                                           
1396      *                                                                                                   
1397      * @param info The data structure describing the shortcut.                                           
1398      *                                                                                                   
1399      * @return A View inflated from R.layout.application.                                                
1400      */                                                                                                  
1401     View createShortcut(ShortcutInfo info) {                                                             
1402         return createShortcut(R.layout.application,                                                      
1403                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1404     }                                                                                                    
1405                                                                                                          
1406     /**                                                                                                  
1407      * Creates a view representing a shortcut inflated from the specified resource.                      
1408      *                                                                                                   
1409      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1410      * @param parent The group the shortcut belongs to.                                                  
1411      * @param info The data structure describing the shortcut.                                           
1412      *                                                                                                   
1413      * @return A View inflated from layoutResId.                                                         
1414      */                                                                                                  
1415     View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                          
1416         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1417         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1418         favorite.setOnClickListener(this);                                                               
1419         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1420         return favorite;                                                                                 
1421     }                                                                                                    
1422                                                                                                          
1423     /**                                                                                                  
1424      * Add a shortcut to the workspace.                                                                  
1425      *                                                                                                   
1426      * @param data The intent describing the shortcut.                                                   
1427      * @param cellInfo The position on screen where to create the shortcut.                              
1428      */                                                                                                  
1429     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1430             int cellY) {                                                                                 
1431         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1432         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1433         CellLayout layout = getCellLayout(container, screenId);                                          
1434                                                                                                          
1435         boolean foundCellSpan = false;                                                                   
1436                                                                                                          
1437         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                             
1438         if (info == null) {                                                                              
1439             return;                                                                                      
1440         }                                                                                                
1441         final View view = createShortcut(info);                                                          
1442                                                                                                          
1443         // First we check if we already know the exact location where we want to add this item.          
1444         if (cellX >= 0 && cellY >= 0) {                                                                  
1445             cellXY[0] = cellX;                                                                           
1446             cellXY[1] = cellY;                                                                           
1447             foundCellSpan = true;                                                                        
1448                                                                                                          
1449             // If appropriate, either create a folder or add to an existing folder                       
1450             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1451                     true, null,null)) {                                                                  
1452                 return;                                                                                  
1453             }                                                                                            
1454             DragObject dragObject = new DragObject();                                                    
1455             dragObject.dragInfo = info;                                                                  
1456             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1457                     true)) {                                                                             
1458                 return;                                                                                  
1459             }                                                                                            
1460         } else if (touchXY != null) {                                                                    
1461             // when dragging and dropping, just find the closest free spot                               
1462             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1463             foundCellSpan = (result != null);                                                            
1464         } else {                                                                                         
1465             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1466         }                                                                                                
1467                                                                                                          
1468         if (!foundCellSpan) {                                                                            
1469             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1470             return;                                                                                      
1471         }                                                                                                
1472                                                                                                          
1473         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1474                                                                                                          
1475         if (!mRestoring) {                                                                               
1476             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1477                     isWorkspaceLocked());                                                                
1478         }                                                                                                
1479     }                                                                                                    
1480                                                                                                          
1481     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1482             int minHeight) {                                                                             
1483         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1484         // We want to account for the extra amount of padding that we are adding to the widget           
1485         // to ensure that it gets the full amount of space that it has requested                         
1486         int requiredWidth = minWidth + padding.left + padding.right;                                     
1487         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1488         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1489     }                                                                                                    
1490                                                                                                          
1491     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1492         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1493     }                                                                                                    
1494                                                                                                          
1495     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1496         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1497     }                                                                                                    
1498                                                                                                          
1499     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1500         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1501     }                                                                                                    
1502                                                                                                          
1503     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1504         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1505                 info.minResizeHeight);                                                                   
1506     }                                                                                                    
1507                                                                                                          
1508     /**                                                                                                  
1509      * Add a widget to the workspace.                                                                    
1510      *                                                                                                   
1511      * @param appWidgetId The app widget id                                                              
1512      * @param cellInfo The position on screen where to create the widget.                                
1513      */                                                                                                  
1514     private void completeAddAppWidget(final int appWidgetId, long container, long screenId,              
1515             AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                           
1516         if (appWidgetInfo == null) {                                                                     
1517             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
1518         }                                                                                                
1519                                                                                                          
1520         // Calculate the grid spans needed to fit this widget                                            
1521         CellLayout layout = getCellLayout(container, screenId);                                          
1522                                                                                                          
1523         int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                      
1524         int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                            
1525                                                                                                          
1526         // Try finding open space on Launcher screen                                                     
1527         // We have saved the position to which the widget was dragged-- this really only matters         
1528         // if we are placing widgets on a "spring-loaded" screen                                         
1529         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1530         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1531         int[] finalSpan = new int[2];                                                                    
1532         boolean foundCellSpan = false;                                                                   
1533         if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                  
1534             cellXY[0] = mPendingAddInfo.cellX;                                                           
1535             cellXY[1] = mPendingAddInfo.cellY;                                                           
1536             spanXY[0] = mPendingAddInfo.spanX;                                                           
1537             spanXY[1] = mPendingAddInfo.spanY;                                                           
1538             foundCellSpan = true;                                                                        
1539         } else if (touchXY != null) {                                                                    
1540             // when dragging and dropping, just find the closest free spot                               
1541             int[] result = layout.findNearestVacantArea(                                                 
1542                     touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                       
1543                     spanXY[1], cellXY, finalSpan);                                                       
1544             spanXY[0] = finalSpan[0];                                                                    
1545             spanXY[1] = finalSpan[1];                                                                    
1546             foundCellSpan = (result != null);                                                            
1547         } else {                                                                                         
1548             foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                  
1549         }                                                                                                
1550                                                                                                          
1551         if (!foundCellSpan) {                                                                            
1552             if (appWidgetId != -1) {                                                                     
1553                 // Deleting an app widget ID is a void call but writes to disk before returning          
1554                 // to the caller...                                                                      
1555                 new AsyncTask<Void, Void, Void>() {                                                      
1556                     public Void doInBackground(Void ... args) {                                          
1557                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                   
1558                         return null;                                                                     
1559                     }                                                                                    
1560                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                        
1561             }                                                                                            
1562             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1563             return;                                                                                      
1564         }                                                                                                
1565                                                                                                          
1566         // Build Launcher-specific widget info and save to database                                      
1567         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                      
1568                 appWidgetInfo.provider);                                                                 
1569         launcherInfo.spanX = spanXY[0];                                                                  
1570         launcherInfo.spanY = spanXY[1];                                                                  
1571         launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                
1572         launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                
1573         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1574                                                                                                          
1575         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1576                 container, screenId, cellXY[0], cellXY[1], false);                                       
1577                                                                                                          
1578         if (!mRestoring) {                                                                               
1579             if (hostView == null) {                                                                      
1580                 // Perform actual inflation because we're live                                           
1581                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1582                 launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                          
1583             } else {                                                                                     
1584                 // The AppWidgetHostView has already been inflated and instantiated                      
1585                 launcherInfo.hostView = hostView;                                                        
1586             }                                                                                            
1587                                                                                                          
1588             launcherInfo.hostView.setTag(launcherInfo);                                                  
1589             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1590             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1591                                                                                                          
1592             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],     
1593                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                        
1594                                                                                                          
1595             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1596         }                                                                                                
1597         resetAddInfo();                                                                                  
1598     }                                                                                                    
1599                                                                                                          
1600     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1601         @Override                                                                                        
1602         public void onReceive(Context context, Intent intent) {                                          
1603             final String action = intent.getAction();                                                    
1604             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1605                 mUserPresent = false;                                                                    
1606                 mDragLayer.clearAllResizeFrames();                                                       
1607                 updateRunning();                                                                         
1608                                                                                                          
1609                 // Reset AllApps to its initial state only if we are not in the middle of                
1610                 // processing a multi-step drop                                                          
1611                 if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {      
1612                     showWorkspace(false);                                                                
1613                 }                                                                                        
1614             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1615                 mUserPresent = true;                                                                     
1616                 updateRunning();                                                                         
1617             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1618                 mModel.resetLoadedState(false, true);                                                    
1619                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1620                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1621             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1622                 mModel.resetLoadedState(false, true);                                                    
1623                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1624                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1625                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1626             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1627                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1628                 getModel().forceReload();                                                                
1629             }                                                                                            
1630         }                                                                                                
1631     };                                                                                                   
1632                                                                                                          
1633     @Override                                                                                            
1634     public void onAttachedToWindow() {                                                                   
1635         super.onAttachedToWindow();                                                                      
1636                                                                                                          
1637         // Listen for broadcasts related to user-presence                                                
1638         final IntentFilter filter = new IntentFilter();                                                  
1639         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1640         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1641         // For handling managed profiles                                                                 
1642         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1643         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1644         if (ENABLE_DEBUG_INTENTS) {                                                                      
1645             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1646             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1647         }                                                                                                
1648         registerReceiver(mReceiver, filter);                                                             
1649         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1650         setupTransparentSystemBarsForLmp();                                                              
1651         mAttached = true;                                                                                
1652         mVisible = true;                                                                                 
1653     }                                                                                                    
1654                                                                                                          
1655     /**                                                                                                  
1656      * Sets up transparent navigation and status bars in LMP.                                            
1657      * This method is a no-op for other platform versions.                                               
1658      */                                                                                                  
1659     @TargetApi(19)                                                                                       
1660     private void setupTransparentSystemBarsForLmp() {                                                    
1661         // TODO(sansid): use the APIs directly when compiling against L sdk.                             
1662         // Currently we use reflection to access the flags and the API to set the transparency           
1663         // on the System bars.                                                                           
1664         if (Utilities.isLmpOrAbove()) {                                                                  
1665             try {                                                                                        
1666                 getWindow().getAttributes().systemUiVisibility |=                                        
1667                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1668                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1669                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1670                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                
1671                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1672                 Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(              
1673                         "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                            
1674                 getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                             
1675                                                                                                          
1676                 Method setStatusBarColorMethod =                                                         
1677                         Window.class.getDeclaredMethod("setStatusBarColor", int.class);                  
1678                 Method setNavigationBarColorMethod =                                                     
1679                         Window.class.getDeclaredMethod("setNavigationBarColor", int.class);              
1680                 setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                          
1681                 setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                      
1682             } catch (NoSuchFieldException e) {                                                           
1683                 Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                    
1684             } catch (NoSuchMethodException ex) {                                                         
1685                 Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                   
1686             } catch (IllegalAccessException e) {                                                         
1687                 Log.w(TAG, "IllegalAccessException while setting up transparent bars");                  
1688             } catch (IllegalArgumentException e) {                                                       
1689                 Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                
1690             } catch (InvocationTargetException e) {                                                      
1691                 Log.w(TAG, "InvocationTargetException while setting up transparent bars");               
1692             } finally {}                                                                                 
1693         }                                                                                                
1694     }                                                                                                    
1695                                                                                                          
1696     @Override                                                                                            
1697     public void onDetachedFromWindow() {                                                                 
1698         super.onDetachedFromWindow();                                                                    
1699         mVisible = false;                                                                                
1700                                                                                                          
1701         if (mAttached) {                                                                                 
1702             unregisterReceiver(mReceiver);                                                               
1703             mAttached = false;                                                                           
1704         }                                                                                                
1705         updateRunning();                                                                                 
1706     }                                                                                                    
1707                                                                                                          
1708     public void onWindowVisibilityChanged(int visibility) {                                              
1709         mVisible = visibility == View.VISIBLE;                                                           
1710         updateRunning();                                                                                 
1711         // The following code used to be in onResume, but it turns out onResume is called when           
1712         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1713         // is a more appropriate event to handle                                                         
1714         if (mVisible) {                                                                                  
1715             mAppsCustomizeTabHost.onWindowVisible();                                                     
1716             if (!mWorkspaceLoading) {                                                                    
1717                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1718                 // We want to let Launcher draw itself at least once before we force it to build         
1719                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1720                 // apps is nice and speedy.                                                              
1721                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1722                     private boolean mStarted = false;                                                    
1723                     public void onDraw() {                                                               
1724                         if (mStarted) return;                                                            
1725                         mStarted = true;                                                                 
1726                         // We delay the layer building a bit in order to give                            
1727                         // other message processing a time to run.  In particular                        
1728                         // this avoids a delay in hiding the IME if it was                               
1729                         // currently shown, because doing that may involve                               
1730                         // some communication back with the app.                                         
1731                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1732                         final ViewTreeObserver.OnDrawListener listener = this;                           
1733                         mWorkspace.post(new Runnable() {                                                 
1734                                 public void run() {                                                      
1735                                     if (mWorkspace != null &&                                            
1736                                             mWorkspace.getViewTreeObserver() != null) {                  
1737                                         mWorkspace.getViewTreeObserver().                                
1738                                                 removeOnDrawListener(listener);                          
1739                                     }                                                                    
1740                                 }                                                                        
1741                             });                                                                          
1742                         return;                                                                          
1743                     }                                                                                    
1744                 });                                                                                      
1745             }                                                                                            
1746             clearTypedText();                                                                            
1747         }                                                                                                
1748     }                                                                                                    
1749                                                                                                          
1750     private void sendAdvanceMessage(long delay) {                                                        
1751         mHandler.removeMessages(ADVANCE_MSG);                                                            
1752         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1753         mHandler.sendMessageDelayed(msg, delay);                                                         
1754         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1755     }                                                                                                    
1756                                                                                                          
1757     private void updateRunning() {                                                                       
1758         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1759         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1760             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1761             if (autoAdvanceRunning) {                                                                    
1762                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1763                 sendAdvanceMessage(delay);                                                               
1764             } else {                                                                                     
1765                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1766                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1767                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1768                 }                                                                                        
1769                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1770                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1771             }                                                                                            
1772         }                                                                                                
1773     }                                                                                                    
1774                                                                                                          
1775     private final Handler mHandler = new Handler() {                                                     
1776         @Override                                                                                        
1777         public void handleMessage(Message msg) {                                                         
1778             if (msg.what == ADVANCE_MSG) {                                                               
1779                 int i = 0;                                                                               
1780                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1781                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1782                     final int delay = mAdvanceStagger * i;                                               
1783                     if (v instanceof Advanceable) {                                                      
1784                        postDelayed(new Runnable() {                                                      
1785                            public void run() {                                                           
1786                                ((Advanceable) v).advance();                                              
1787                            }                                                                             
1788                        }, delay);                                                                        
1789                     }                                                                                    
1790                     i++;                                                                                 
1791                 }                                                                                        
1792                 sendAdvanceMessage(mAdvanceInterval);                                                    
1793             }                                                                                            
1794         }                                                                                                
1795     };                                                                                                   
1796                                                                                                          
1797     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1798         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1799         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1800         if (v instanceof Advanceable) {                                                                  
1801             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1802             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1803             updateRunning();                                                                             
1804         }                                                                                                
1805     }                                                                                                    
1806                                                                                                          
1807     void removeWidgetToAutoAdvance(View hostView) {                                                      
1808         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1809             mWidgetsToAdvance.remove(hostView);                                                          
1810             updateRunning();                                                                             
1811         }                                                                                                
1812     }                                                                                                    
1813                                                                                                          
1814     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1815         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1816         launcherInfo.hostView = null;                                                                    
1817     }                                                                                                    
1818                                                                                                          
1819     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1820         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1821         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1822     }                                                                                                    
1823                                                                                                          
1824     public DragLayer getDragLayer() {                                                                    
1825         return mDragLayer;                                                                               
1826     }                                                                                                    
1827                                                                                                          
1828     public Workspace getWorkspace() {                                                                    
1829         return mWorkspace;                                                                               
1830     }                                                                                                    
1831                                                                                                          
1832     public Hotseat getHotseat() {                                                                        
1833         return mHotseat;                                                                                 
1834     }                                                                                                    
1835                                                                                                          
1836     public ViewGroup getOverviewPanel() {                                                                
1837         return mOverviewPanel;                                                                           
1838     }                                                                                                    
1839                                                                                                          
1840     public SearchDropTargetBar getSearchBar() {                                                          
1841         return mSearchDropTargetBar;                                                                     
1842     }                                                                                                    
1843                                                                                                          
1844     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1845         return mAppWidgetHost;                                                                           
1846     }                                                                                                    
1847                                                                                                          
1848     public LauncherModel getModel() {                                                                    
1849         return mModel;                                                                                   
1850     }                                                                                                    
1851                                                                                                          
1852     protected SharedPreferences getSharedPrefs() {                                                       
1853         return mSharedPrefs;                                                                             
1854     }                                                                                                    
1855                                                                                                          
1856     public void closeSystemDialogs() {                                                                   
1857         getWindow().closeAllPanels();                                                                    
1858                                                                                                          
1859         // Whatever we were doing is hereby canceled.                                                    
1860         setWaitingForResult(false);                                                                      
1861     }                                                                                                    
1862                                                                                                          
1863     @Override                                                                                            
1864     protected void onNewIntent(Intent intent) {                                                          
1865         long startTime = 0;                                                                              
1866         if (DEBUG_RESUME_TIME) {                                                                         
1867             startTime = System.currentTimeMillis();                                                      
1868         }                                                                                                
1869         super.onNewIntent(intent);                                                                       
1870                                                                                                          
1871         // Close the menu                                                                                
1872         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1873             // also will cancel mWaitingForResult.                                                       
1874             closeSystemDialogs();                                                                        
1875                                                                                                          
1876             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1877                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1878                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1879                                                                                                          
1880             if (mWorkspace == null) {                                                                    
1881                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1882                 return;                                                                                  
1883             }                                                                                            
1884             Folder openFolder = mWorkspace.getOpenFolder();                                              
1885             // In all these cases, only animate if we're already on home                                 
1886             mWorkspace.exitWidgetResizeMode();                                                           
1887             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1888                     openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                     
1889                 mWorkspace.moveToDefaultScreen(true);                                                    
1890             }                                                                                            
1891                                                                                                          
1892             closeFolder();                                                                               
1893             exitSpringLoadedDragMode();                                                                  
1894                                                                                                          
1895             // If we are already on home, then just animate back to the workspace,                       
1896             // otherwise, just wait until onResume to set the state back to Workspace                    
1897             if (alreadyOnHome) {                                                                         
1898                 showWorkspace(true);                                                                     
1899             } else {                                                                                     
1900                 mOnResumeState = State.WORKSPACE;                                                        
1901             }                                                                                            
1902                                                                                                          
1903             final View v = getWindow().peekDecorView();                                                  
1904             if (v != null && v.getWindowToken() != null) {                                               
1905                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1906                         INPUT_METHOD_SERVICE);                                                           
1907                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1908             }                                                                                            
1909                                                                                                          
1910             // Reset the apps customize page                                                             
1911             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1912                 mAppsCustomizeTabHost.reset();                                                           
1913             }                                                                                            
1914                                                                                                          
1915             onHomeIntent();                                                                              
1916         }                                                                                                
1917                                                                                                          
1918         if (DEBUG_RESUME_TIME) {                                                                         
1919             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1920         }                                                                                                
1921     }                                                                                                    
1922                                                                                                          
1923     /**                                                                                                  
1924      * Override point for subclasses to prevent movement to the default screen when the home             
1925      * button is pressed. Used (for example) in GEL, to prevent movement during a search.                
1926      */                                                                                                  
1927     protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                          
1928         return true;                                                                                     
1929     }                                                                                                    
1930                                                                                                          
1931     /**                                                                                                  
1932      * Override point for subclasses to provide custom behaviour for when a home intent is fired.        
1933      */                                                                                                  
1934     protected void onHomeIntent() {                                                                      
1935         // Do nothing                                                                                    
1936     }                                                                                                    
1937                                                                                                          
1938     @Override                                                                                            
1939     public void onRestoreInstanceState(Bundle state) {                                                   
1940         super.onRestoreInstanceState(state);                                                             
1941         for (int page: mSynchronouslyBoundPages) {                                                       
1942             mWorkspace.restoreInstanceStateForChild(page);                                               
1943         }                                                                                                
1944     }                                                                                                    
1945                                                                                                          
1946     @Override                                                                                            
1947     protected void onSaveInstanceState(Bundle outState) {                                                
1948         if (mWorkspace.getChildCount() > 0) {                                                            
1949             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1950                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1951         }                                                                                                
1952         super.onSaveInstanceState(outState);                                                             
1953                                                                                                          
1954         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1955         // We close any open folder since it will not be re-opened, and we need to make sure             
1956         // this state is reflected.                                                                      
1957         closeFolder();                                                                                   
1958                                                                                                          
1959         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1960                 mWaitingForResult) {                                                                     
1961             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1962             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1963             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1964             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1965             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1966             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1967             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1968             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1969         }                                                                                                
1970                                                                                                          
1971         if (mFolderInfo != null && mWaitingForResult) {                                                  
1972             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
1973             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
1974         }                                                                                                
1975                                                                                                          
1976         // Save the current AppsCustomize tab                                                            
1977         if (mAppsCustomizeTabHost != null) {                                                             
1978             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
1979             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
1980             if (currentTabTag != null) {                                                                 
1981                 outState.putString("apps_customize_currentTab", currentTabTag);                          
1982             }                                                                                            
1983             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
1984             outState.putInt("apps_customize_currentIndex", currentIndex);                                
1985         }                                                                                                
1986         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1987     }                                                                                                    
1988                                                                                                          
1989     @Override                                                                                            
1990     public void onDestroy() {                                                                            
1991         super.onDestroy();                                                                               
1992                                                                                                          
1993         // Remove all pending runnables                                                                  
1994         mHandler.removeMessages(ADVANCE_MSG);                                                            
1995         mHandler.removeMessages(0);                                                                      
1996         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
1997                                                                                                          
1998         // Stop callbacks from LauncherModel                                                             
1999         LauncherAppState app = (LauncherAppState.getInstance());                                         
2000                                                                                                          
2001         // It's possible to receive onDestroy after a new Launcher activity has                          
2002         // been created. In this case, don't interfere with the new Launcher.                            
2003         if (mModel.isCurrentCallbacks(this)) {                                                           
2004             mModel.stopLoader();                                                                         
2005             app.setLauncher(null);                                                                       
2006         }                                                                                                
2007                                                                                                          
2008         try {                                                                                            
2009             mAppWidgetHost.stopListening();                                                              
2010         } catch (NullPointerException ex) {                                                              
2011             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2012         }                                                                                                
2013         mAppWidgetHost = null;                                                                           
2014                                                                                                          
2015         mWidgetsToAdvance.clear();                                                                       
2016                                                                                                          
2017         TextKeyListener.getInstance().release();                                                         
2018                                                                                                          
2019         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2020         // to prevent leaking Launcher activities on orientation change.                                 
2021         if (mModel != null) {                                                                            
2022             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2023         }                                                                                                
2024                                                                                                          
2025         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2026         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2027                                                                                                          
2028         mDragLayer.clearAllResizeFrames();                                                               
2029         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2030         mWorkspace.removeAllWorkspaceScreens();                                                          
2031         mWorkspace = null;                                                                               
2032         mDragController = null;                                                                          
2033                                                                                                          
2034         PackageInstallerCompat.getInstance(this).onStop();                                               
2035         LauncherAnimUtils.onDestroyActivity();                                                           
2036     }                                                                                                    
2037                                                                                                          
2038     public DragController getDragController() {                                                          
2039         return mDragController;                                                                          
2040     }                                                                                                    
2041                                                                                                          
2042     @Override                                                                                            
2043     public void startActivityForResult(Intent intent, int requestCode) {                                 
2044         if (requestCode >= 0) {                                                                          
2045             setWaitingForResult(true);                                                                   
2046         }                                                                                                
2047         super.startActivityForResult(intent, requestCode);                                               
2048     }                                                                                                    
2049                                                                                                          
2050     /**                                                                                                  
2051      * Indicates that we want global search for this activity by setting the globalSearch                
2052      * argument for {@link #startSearch} to true.                                                        
2053      */                                                                                                  
2054     @Override                                                                                            
2055     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2056             Bundle appSearchData, boolean globalSearch) {                                                
2057                                                                                                          
2058         showWorkspace(true);                                                                             
2059                                                                                                          
2060         if (initialQuery == null) {                                                                      
2061             // Use any text typed in the launcher as the initial query                                   
2062             initialQuery = getTypedText();                                                               
2063         }                                                                                                
2064         if (appSearchData == null) {                                                                     
2065             appSearchData = new Bundle();                                                                
2066             appSearchData.putString("source", "launcher-search");                                        
2067         }                                                                                                
2068         Rect sourceBounds = new Rect();                                                                  
2069         if (mSearchDropTargetBar != null) {                                                              
2070             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2071         }                                                                                                
2072                                                                                                          
2073         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2074                 appSearchData, sourceBounds);                                                            
2075         if (clearTextImmediately) {                                                                      
2076             clearTypedText();                                                                            
2077         }                                                                                                
2078     }                                                                                                    
2079                                                                                                          
2080     /**                                                                                                  
2081      * Start a text search.                                                                              
2082      *                                                                                                   
2083      * @return {@code true} if the search will start immediately, so any further keypresses              
2084      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2085      * to buffer keypresses.                                                                             
2086      */                                                                                                  
2087     public boolean startSearch(String initialQuery,                                                      
2088             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2089         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2090                 appSearchData, sourceBounds);                                                            
2091         return false;                                                                                    
2092     }                                                                                                    
2093                                                                                                          
2094     /**                                                                                                  
2095      * Starts the global search activity. This code is a copied from SearchManager                       
2096      */                                                                                                  
2097     private void startGlobalSearch(String initialQuery,                                                  
2098             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2099         final SearchManager searchManager =                                                              
2100             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2101         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2102         if (globalSearchActivity == null) {                                                              
2103             Log.w(TAG, "No global search activity found.");                                              
2104             return;                                                                                      
2105         }                                                                                                
2106         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2107         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2108         intent.setComponent(globalSearchActivity);                                                       
2109         // Make sure that we have a Bundle to put source in                                              
2110         if (appSearchData == null) {                                                                     
2111             appSearchData = new Bundle();                                                                
2112         } else {                                                                                         
2113             appSearchData = new Bundle(appSearchData);                                                   
2114         }                                                                                                
2115         // Set source to package name of app that starts global search, if not set already.              
2116         if (!appSearchData.containsKey("source")) {                                                      
2117             appSearchData.putString("source", getPackageName());                                         
2118         }                                                                                                
2119         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2120         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2121             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2122         }                                                                                                
2123         if (selectInitialQuery) {                                                                        
2124             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2125         }                                                                                                
2126         intent.setSourceBounds(sourceBounds);                                                            
2127         try {                                                                                            
2128             startActivity(intent);                                                                       
2129         } catch (ActivityNotFoundException ex) {                                                         
2130             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2131         }                                                                                                
2132     }                                                                                                    
2133                                                                                                          
2134     public boolean isOnCustomContent() {                                                                 
2135         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2136     }                                                                                                    
2137                                                                                                          
2138     @Override                                                                                            
2139     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2140         super.onPrepareOptionsMenu(menu);                                                                
2141         if (!isOnCustomContent()) {                                                                      
2142             // Close any open folders                                                                    
2143             closeFolder();                                                                               
2144             // Stop resizing any widgets                                                                 
2145             mWorkspace.exitWidgetResizeMode();                                                           
2146             if (!mWorkspace.isInOverviewMode()) {                                                        
2147                 // Show the overview mode                                                                
2148                 showOverviewMode(true);                                                                  
2149             } else {                                                                                     
2150                 showWorkspace(true);                                                                     
2151             }                                                                                            
2152         }                                                                                                
2153         return false;                                                                                    
2154     }                                                                                                    
2155                                                                                                          
2156     @Override                                                                                            
2157     public boolean onSearchRequested() {                                                                 
2158         startSearch(null, false, null, true);                                                            
2159         // Use a custom animation for launching search                                                   
2160         return true;                                                                                     
2161     }                                                                                                    
2162                                                                                                          
2163     public boolean isWorkspaceLocked() {                                                                 
2164         return mWorkspaceLoading || mWaitingForResult;                                                   
2165     }                                                                                                    
2166                                                                                                          
2167     public boolean isWorkspaceLoading() {                                                                
2168         return mWorkspaceLoading;                                                                        
2169     }                                                                                                    
2170                                                                                                          
2171     private void setWorkspaceLoading(boolean value) {                                                    
2172         boolean isLocked = isWorkspaceLocked();                                                          
2173         mWorkspaceLoading = value;                                                                       
2174         if (isLocked != isWorkspaceLocked()) {                                                           
2175             onWorkspaceLockedChanged();                                                                  
2176         }                                                                                                
2177     }                                                                                                    
2178                                                                                                          
2179     private void setWaitingForResult(boolean value) {                                                    
2180         boolean isLocked = isWorkspaceLocked();                                                          
2181         mWaitingForResult = value;                                                                       
2182         if (isLocked != isWorkspaceLocked()) {                                                           
2183             onWorkspaceLockedChanged();                                                                  
2184         }                                                                                                
2185     }                                                                                                    
2186                                                                                                          
2187     protected void onWorkspaceLockedChanged() { }                                                        
2188                                                                                                          
2189     private void resetAddInfo() {                                                                        
2190         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2191         mPendingAddInfo.screenId = -1;                                                                   
2192         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2193         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2194         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2195         mPendingAddInfo.dropPos = null;                                                                  
2196     }                                                                                                    
2197                                                                                                          
2198     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2199             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2200         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2201     }                                                                                                    
2202                                                                                                          
2203     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2204             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int          
2205             delay) {                                                                                     
2206         if (appWidgetInfo.configure != null) {                                                           
2207             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2208             mPendingAddWidgetId = appWidgetId;                                                           
2209                                                                                                          
2210             // Launch over to configure widget, if needed                                                
2211             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2212                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2213                                                                                                          
2214         } else {                                                                                         
2215             // Otherwise just add it                                                                     
2216             Runnable onComplete = new Runnable() {                                                       
2217                 @Override                                                                                
2218                 public void run() {                                                                      
2219                     // Exit spring loaded mode if necessary after adding the widget                      
2220                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2221                             null);                                                                       
2222                 }                                                                                        
2223             };                                                                                           
2224             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2225                     appWidgetInfo);                                                                      
2226             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2227         }                                                                                                
2228     }                                                                                                    
2229                                                                                                          
2230     protected void moveToCustomContentScreen(boolean animate) {                                          
2231         // Close any folders that may be open.                                                           
2232         closeFolder();                                                                                   
2233         mWorkspace.moveToCustomContentScreen(animate);                                                   
2234     }                                                                                                    
2235     /**                                                                                                  
2236      * Process a shortcut drop.                                                                          
2237      *                                                                                                   
2238      * @param componentName The name of the component                                                    
2239      * @param screenId The ID of the screen where it should be added                                     
2240      * @param cell The cell it should be added to, optional                                              
2241      * @param position The location on the screen where it was dropped, optional                         
2242      */                                                                                                  
2243     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2244             int[] cell, int[] loc) {                                                                     
2245         resetAddInfo();                                                                                  
2246         mPendingAddInfo.container = container;                                                           
2247         mPendingAddInfo.screenId = screenId;                                                             
2248         mPendingAddInfo.dropPos = loc;                                                                   
2249                                                                                                          
2250         if (cell != null) {                                                                              
2251             mPendingAddInfo.cellX = cell[0];                                                             
2252             mPendingAddInfo.cellY = cell[1];                                                             
2253         }                                                                                                
2254                                                                                                          
2255         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2256         createShortcutIntent.setComponent(componentName);                                                
2257         processShortcut(createShortcutIntent);                                                           
2258     }                                                                                                    
2259                                                                                                          
2260     /**                                                                                                  
2261      * Process a widget drop.                                                                            
2262      *                                                                                                   
2263      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2264      * @param screenId The ID of the screen where it should be added                                     
2265      * @param cell The cell it should be added to, optional                                              
2266      * @param position The location on the screen where it was dropped, optional                         
2267      */                                                                                                  
2268     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                  
2269             int[] cell, int[] span, int[] loc) {                                                         
2270         resetAddInfo();                                                                                  
2271         mPendingAddInfo.container = info.container = container;                                          
2272         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2273         mPendingAddInfo.dropPos = loc;                                                                   
2274         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2275         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2276                                                                                                          
2277         if (cell != null) {                                                                              
2278             mPendingAddInfo.cellX = cell[0];                                                             
2279             mPendingAddInfo.cellY = cell[1];                                                             
2280         }                                                                                                
2281         if (span != null) {                                                                              
2282             mPendingAddInfo.spanX = span[0];                                                             
2283             mPendingAddInfo.spanY = span[1];                                                             
2284         }                                                                                                
2285                                                                                                          
2286         AppWidgetHostView hostView = info.boundWidget;                                                   
2287         int appWidgetId;                                                                                 
2288         if (hostView != null) {                                                                          
2289             appWidgetId = hostView.getAppWidgetId();                                                     
2290             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2291         } else {                                                                                         
2292             // In this case, we either need to start an activity to get permission to bind               
2293             // the widget, or we need to start an activity to configure the widget, or both.             
2294             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2295             Bundle options = info.bindOptions;                                                           
2296                                                                                                          
2297             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2298                     appWidgetId, info.info, options);                                                    
2299             if (success) {                                                                               
2300                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2301             } else {                                                                                     
2302                 mPendingAddWidgetInfo = info.info;                                                       
2303                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2304                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2305                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2306                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2307                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2308                 // TODO: we need to make sure that this accounts for the options bundle.                 
2309                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2310                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2311             }                                                                                            
2312         }                                                                                                
2313     }                                                                                                    
2314                                                                                                          
2315     void processShortcut(Intent intent) {                                                                
2316         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2317     }                                                                                                    
2318                                                                                                          
2319     void processWallpaper(Intent intent) {                                                               
2320         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2321     }                                                                                                    
2322                                                                                                          
2323     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2324             int cellY) {                                                                                 
2325         final FolderInfo folderInfo = new FolderInfo();                                                  
2326         folderInfo.title = getText(R.string.folder_name);                                                
2327                                                                                                          
2328         // Update the model                                                                              
2329         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2330                 false);                                                                                  
2331         sFolders.put(folderInfo.id, folderInfo);                                                         
2332                                                                                                          
2333         // Create the view                                                                               
2334         FolderIcon newFolder =                                                                           
2335             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2336         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2337                 isWorkspaceLocked());                                                                    
2338         // Force measure the new folder icon                                                             
2339         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2340         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2341         return newFolder;                                                                                
2342     }                                                                                                    
2343                                                                                                          
2344     void removeFolder(FolderInfo folder) {                                                               
2345         sFolders.remove(folder.id);                                                                      
2346     }                                                                                                    
2347                                                                                                          
2348     protected ComponentName getWallpaperPickerComponent() {                                              
2349         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2350     }                                                                                                    
2351                                                                                                          
2352     /**                                                                                                  
2353      * Registers various content observers. The current implementation registers                         
2354      * only a favorites observer to keep track of the favorites applications.                            
2355      */                                                                                                  
2356     private void registerContentObservers() {                                                            
2357         ContentResolver resolver = getContentResolver();                                                 
2358         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2359                 true, mWidgetObserver);                                                                  
2360     }                                                                                                    
2361                                                                                                          
2362     @Override                                                                                            
2363     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2364         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2365             switch (event.getKeyCode()) {                                                                
2366                 case KeyEvent.KEYCODE_HOME:                                                              
2367                     return true;                                                                         
2368                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2369                     if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                        
2370                         dumpState();                                                                     
2371                         return true;                                                                     
2372                     }                                                                                    
2373                     break;                                                                               
2374             }                                                                                            
2375         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2376             switch (event.getKeyCode()) {                                                                
2377                 case KeyEvent.KEYCODE_HOME:                                                              
2378                     return true;                                                                         
2379             }                                                                                            
2380         }                                                                                                
2381                                                                                                          
2382         return super.dispatchKeyEvent(event);                                                            
2383     }                                                                                                    
2384                                                                                                          
2385     @Override                                                                                            
2386     public void onBackPressed() {                                                                        
2387         if (isAllAppsVisible()) {                                                                        
2388             if (mAppsCustomizeContent.getContentType() ==                                                
2389                     AppsCustomizePagedView.ContentType.Applications) {                                   
2390                 showWorkspace(true);                                                                     
2391             } else {                                                                                     
2392                 showOverviewMode(true);                                                                  
2393             }                                                                                            
2394         } else if (mWorkspace.isInOverviewMode()) {                                                      
2395             mWorkspace.exitOverviewMode(true);                                                           
2396         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2397             Folder openFolder = mWorkspace.getOpenFolder();                                              
2398             if (openFolder.isEditingName()) {                                                            
2399                 openFolder.dismissEditingName();                                                         
2400             } else {                                                                                     
2401                 closeFolder();                                                                           
2402             }                                                                                            
2403         } else {                                                                                         
2404             mWorkspace.exitWidgetResizeMode();                                                           
2405                                                                                                          
2406             // Back button is a no-op here, but give at least some feedback for the button press         
2407             mWorkspace.showOutlinesTemporarily();                                                        
2408         }                                                                                                
2409     }                                                                                                    
2410                                                                                                          
2411     /**                                                                                                  
2412      * Re-listen when widgets are reset.                                                                 
2413      */                                                                                                  
2414     private void onAppWidgetReset() {                                                                    
2415         if (mAppWidgetHost != null) {                                                                    
2416             mAppWidgetHost.startListening();                                                             
2417         }                                                                                                
2418     }                                                                                                    
2419                                                                                                          
2420     /**                                                                                                  
2421      * Launches the intent referred by the clicked shortcut.                                             
2422      *                                                                                                   
2423      * @param v The view representing the clicked shortcut.                                              
2424      */                                                                                                  
2425     public void onClick(View v) {                                                                        
2426         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2427         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2428         if (v.getWindowToken() == null) {                                                                
2429             return;                                                                                      
2430         }                                                                                                
2431                                                                                                          
2432         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2433             return;                                                                                      
2434         }                                                                                                
2435                                                                                                          
2436         if (v instanceof Workspace) {                                                                    
2437             if (mWorkspace.isInOverviewMode()) {                                                         
2438                 mWorkspace.exitOverviewMode(true);                                                       
2439             }                                                                                            
2440             return;                                                                                      
2441         }                                                                                                
2442                                                                                                          
2443         if (v instanceof CellLayout) {                                                                   
2444             if (mWorkspace.isInOverviewMode()) {                                                         
2445                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2446             }                                                                                            
2447         }                                                                                                
2448                                                                                                          
2449         Object tag = v.getTag();                                                                         
2450         if (tag instanceof ShortcutInfo) {                                                               
2451             onClickAppShortcut(v);                                                                       
2452         } else if (tag instanceof FolderInfo) {                                                          
2453             if (v instanceof FolderIcon) {                                                               
2454                 onClickFolderIcon(v);                                                                    
2455             }                                                                                            
2456         } else if (v == mAllAppsButton) {                                                                
2457             onClickAllAppsButton(v);                                                                     
2458         } else if (tag instanceof AppInfo) {                                                             
2459             startAppShortcutOrInfoActivity(v);                                                           
2460         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2461             if (v instanceof PendingAppWidgetHostView) {                                                 
2462                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2463             }                                                                                            
2464         }                                                                                                
2465     }                                                                                                    
2466                                                                                                          
2467     public void onClickPagedViewIcon(View v) {                                                           
2468         startAppShortcutOrInfoActivity(v);                                                               
2469     }                                                                                                    
2470                                                                                                          
2471     public boolean onTouch(View v, MotionEvent event) {                                                  
2472         return false;                                                                                    
2473     }                                                                                                    
2474                                                                                                          
2475     /**                                                                                                  
2476      * Event handler for the app widget view which has not fully restored.                               
2477      */                                                                                                  
2478     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2479         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2480         if (v.isReadyForClickSetup()) {                                                                  
2481             int widgetId = info.appWidgetId;                                                             
2482             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2483             if (appWidgetInfo != null) {                                                                 
2484                 mPendingAddWidgetInfo = appWidgetInfo;                                                   
2485                 mPendingAddInfo.copyFrom(info);                                                          
2486                 mPendingAddWidgetId = widgetId;                                                          
2487                                                                                                          
2488                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2489                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2490             }                                                                                            
2491         } else if (info.installProgress < 0) {                                                           
2492             // The install has not been queued                                                           
2493             final String packageName = info.providerName.getPackageName();                               
2494             showBrokenAppInstallDialog(packageName,                                                      
2495                 new DialogInterface.OnClickListener() {                                                  
2496                     public void onClick(DialogInterface dialog, int id) {                                
2497                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2498                     }                                                                                    
2499                 });                                                                                      
2500         } else {                                                                                         
2501             // Download has started.                                                                     
2502             final String packageName = info.providerName.getPackageName();                               
2503             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2504         }                                                                                                
2505     }                                                                                                    
2506                                                                                                          
2507     /**                                                                                                  
2508      * Event handler for the search button                                                               
2509      *                                                                                                   
2510      * @param v The view that was clicked.                                                               
2511      */                                                                                                  
2512     public void onClickSearchButton(View v) {                                                            
2513         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2514                                                                                                          
2515         onSearchRequested();                                                                             
2516     }                                                                                                    
2517                                                                                                          
2518     /**                                                                                                  
2519      * Event handler for the voice button                                                                
2520      *                                                                                                   
2521      * @param v The view that was clicked.                                                               
2522      */                                                                                                  
2523     public void onClickVoiceButton(View v) {                                                             
2524         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2525                                                                                                          
2526         startVoice();                                                                                    
2527     }                                                                                                    
2528                                                                                                          
2529     public void startVoice() {                                                                           
2530         try {                                                                                            
2531             final SearchManager searchManager =                                                          
2532                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);                            
2533             ComponentName activityName = searchManager.getGlobalSearchActivity();                        
2534             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2535             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2536             if (activityName != null) {                                                                  
2537                 intent.setPackage(activityName.getPackageName());                                        
2538             }                                                                                            
2539             startActivity(null, intent, "onClickVoiceButton");                                           
2540         } catch (ActivityNotFoundException e) {                                                          
2541             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2542             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2543             startActivitySafely(null, intent, "onClickVoiceButton");                                     
2544         }                                                                                                
2545     }                                                                                                    
2546                                                                                                          
2547     /**                                                                                                  
2548      * Event handler for the "grid" button that appears on the home screen, which                        
2549      * enters all apps mode.                                                                             
2550      *                                                                                                   
2551      * @param v The view that was clicked.                                                               
2552      */                                                                                                  
2553     protected void onClickAllAppsButton(View v) {                                                        
2554         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2555         if (isAllAppsVisible()) {                                                                        
2556             showWorkspace(true);                                                                         
2557         } else {                                                                                         
2558             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                   
2559         }                                                                                                
2560     }                                                                                                    
2561                                                                                                          
2562     private void showBrokenAppInstallDialog(final String packageName,                                    
2563             DialogInterface.OnClickListener onSearchClickListener) {                                     
2564         new AlertDialog.Builder(this)                                                                    
2565             .setTitle(R.string.abandoned_promises_title)                                                 
2566             .setMessage(R.string.abandoned_promise_explanation)                                          
2567             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2568             .setNeutralButton(R.string.abandoned_clean_this,                                             
2569                 new DialogInterface.OnClickListener() {                                                  
2570                     public void onClick(DialogInterface dialog, int id) {                                
2571                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2572                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2573                     }                                                                                    
2574                 })                                                                                       
2575             .create().show();                                                                            
2576         return;                                                                                          
2577     }                                                                                                    
2578                                                                                                          
2579     /**                                                                                                  
2580      * Event handler for an app shortcut click.                                                          
2581      *                                                                                                   
2582      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2583      */                                                                                                  
2584     protected void onClickAppShortcut(final View v) {                                                    
2585         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2586         Object tag = v.getTag();                                                                         
2587         if (!(tag instanceof ShortcutInfo)) {                                                            
2588             throw new IllegalArgumentException("Input must be a Shortcut");                              
2589         }                                                                                                
2590                                                                                                          
2591         // Open shortcut                                                                                 
2592         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2593                                                                                                          
2594         if (shortcut.isDisabled != 0) {                                                                  
2595             int error = R.string.activity_not_available;                                                 
2596             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2597                 error = R.string.safemode_shortcut_error;                                                
2598             }                                                                                            
2599             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2600             return;                                                                                      
2601         }                                                                                                
2602                                                                                                          
2603         final Intent intent = shortcut.intent;                                                           
2604                                                                                                          
2605         // Check for special shortcuts                                                                   
2606         if (intent.getComponent() != null) {                                                             
2607             final String shortcutClass = intent.getComponent().getClassName();                           
2608                                                                                                          
2609             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2610                 MemoryDumpActivity.startDump(this);                                                      
2611                 return;                                                                                  
2612             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2613                 toggleShowWeightWatcher();                                                               
2614                 return;                                                                                  
2615             }                                                                                            
2616         }                                                                                                
2617                                                                                                          
2618         // Check for abandoned promise                                                                   
2619         if ((v instanceof BubbleTextView)                                                                
2620                 && shortcut.isPromise()                                                                  
2621                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2622             showBrokenAppInstallDialog(                                                                  
2623                     shortcut.getTargetComponent().getPackageName(),                                      
2624                     new DialogInterface.OnClickListener() {                                              
2625                         public void onClick(DialogInterface dialog, int id) {                            
2626                             startAppShortcutOrInfoActivity(v);                                           
2627                         }                                                                                
2628                     });                                                                                  
2629             return;                                                                                      
2630         }                                                                                                
2631                                                                                                          
2632         // Start activities                                                                              
2633         startAppShortcutOrInfoActivity(v);                                                               
2634     }                                                                                                    
2635                                                                                                          
2636     private void startAppShortcutOrInfoActivity(View v) {                                                
2637         Object tag = v.getTag();                                                                         
2638         final ShortcutInfo shortcut;                                                                     
2639         final Intent intent;                                                                             
2640         if (tag instanceof ShortcutInfo) {                                                               
2641             shortcut = (ShortcutInfo) tag;                                                               
2642             intent = shortcut.intent;                                                                    
2643             int[] pos = new int[2];                                                                      
2644             v.getLocationOnScreen(pos);                                                                  
2645             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2646                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2647                                                                                                          
2648         } else if (tag instanceof AppInfo) {                                                             
2649             shortcut = null;                                                                             
2650             intent = ((AppInfo) tag).intent;                                                             
2651         } else {                                                                                         
2652             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2653         }                                                                                                
2654                                                                                                          
2655         boolean success = startActivitySafely(v, intent, tag);                                           
2656         mStats.recordLaunch(intent, shortcut);                                                           
2657                                                                                                          
2658         if (success && v instanceof BubbleTextView) {                                                    
2659             mWaitingForResume = (BubbleTextView) v;                                                      
2660             mWaitingForResume.setStayPressed(true);                                                      
2661         }                                                                                                
2662     }                                                                                                    
2663                                                                                                          
2664     /**                                                                                                  
2665      * Event handler for a folder icon click.                                                            
2666      *                                                                                                   
2667      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2668      */                                                                                                  
2669     protected void onClickFolderIcon(View v) {                                                           
2670         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2671         if (!(v instanceof FolderIcon)){                                                                 
2672             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2673         }                                                                                                
2674                                                                                                          
2675         FolderIcon folderIcon = (FolderIcon) v;                                                          
2676         final FolderInfo info = folderIcon.getFolderInfo();                                              
2677         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2678                                                                                                          
2679         // If the folder info reports that the associated folder is open, then verify that               
2680         // it is actually opened. There have been a few instances where this gets out of sync.           
2681         if (info.opened && openFolder == null) {                                                         
2682             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2683                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2684             info.opened = false;                                                                         
2685         }                                                                                                
2686                                                                                                          
2687         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2688             // Close any open folder                                                                     
2689             closeFolder();                                                                               
2690             // Open the requested folder                                                                 
2691             openFolder(folderIcon);                                                                      
2692         } else {                                                                                         
2693             // Find the open folder...                                                                   
2694             int folderScreen;                                                                            
2695             if (openFolder != null) {                                                                    
2696                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2697                 // .. and close it                                                                       
2698                 closeFolder(openFolder);                                                                 
2699                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2700                     // Close any folder open on the current screen                                       
2701                     closeFolder();                                                                       
2702                     // Pull the folder onto this screen                                                  
2703                     openFolder(folderIcon);                                                              
2704                 }                                                                                        
2705             }                                                                                            
2706         }                                                                                                
2707     }                                                                                                    
2708                                                                                                          
2709     /**                                                                                                  
2710      * Event handler for the (Add) Widgets button that appears after a long press                        
2711      * on the home screen.                                                                               
2712      */                                                                                                  
2713     protected void onClickAddWidgetButton(View view) {                                                   
2714         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2715         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                             
2716     }                                                                                                    
2717                                                                                                          
2718     /**                                                                                                  
2719      * Event handler for the wallpaper picker button that appears after a long press                     
2720      * on the home screen.                                                                               
2721      */                                                                                                  
2722     protected void onClickWallpaperPicker(View v) {                                                      
2723         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2724         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2725         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2726         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2727     }                                                                                                    
2728                                                                                                          
2729     /**                                                                                                  
2730      * Event handler for a click on the settings button that appears after a long press                  
2731      * on the home screen.                                                                               
2732      */                                                                                                  
2733     protected void onClickSettingsButton(View v) {                                                       
2734         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2735     }                                                                                                    
2736                                                                                                          
2737     public void onTouchDownAllAppsButton(View v) {                                                       
2738         // Provide the same haptic feedback that the system offers for virtual keys.                     
2739         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2740     }                                                                                                    
2741                                                                                                          
2742     public void performHapticFeedbackOnTouchDown(View v) {                                               
2743         // Provide the same haptic feedback that the system offers for virtual keys.                     
2744         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2745     }                                                                                                    
2746                                                                                                          
2747     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2748         if (mHapticFeedbackTouchListener == null) {                                                      
2749             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2750                 @Override                                                                                
2751                 public boolean onTouch(View v, MotionEvent event) {                                      
2752                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2753                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2754                     }                                                                                    
2755                     return false;                                                                        
2756                 }                                                                                        
2757             };                                                                                           
2758         }                                                                                                
2759         return mHapticFeedbackTouchListener;                                                             
2760     }                                                                                                    
2761                                                                                                          
2762     public void onDragStarted(View view) {}                                                              
2763                                                                                                          
2764     /**                                                                                                  
2765      * Called when the user stops interacting with the launcher.                                         
2766      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2767      */                                                                                                  
2768     protected void onInteractionEnd() {}                                                                 
2769                                                                                                          
2770     /**                                                                                                  
2771      * Called when the user starts interacting with the launcher.                                        
2772      * The possible interactions are:                                                                    
2773      *  - open all apps                                                                                  
2774      *  - reorder an app shortcut, or a widget                                                           
2775      *  - open the overview mode.                                                                        
2776      * This is a good time to stop doing things that only make sense                                     
2777      * when the user is on the homescreen and not doing housekeeping.                                    
2778      */                                                                                                  
2779     protected void onInteractionBegin() {}                                                               
2780                                                                                                          
2781     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2782         String packageName = componentName.getPackageName();                                             
2783         try {                                                                                            
2784             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2785             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2786             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2787         } catch (SecurityException e) {                                                                  
2788             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2789             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2790         } catch (ActivityNotFoundException e) {                                                          
2791             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2792             Log.e(TAG, "Unable to launch settings");                                                     
2793         }                                                                                                
2794     }                                                                                                    
2795                                                                                                          
2796     // returns true if the activity was started                                                          
2797     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2798             UserHandleCompat user) {                                                                     
2799         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2800             // System applications cannot be installed. For now, show a toast explaining that.           
2801             // We may give them the option of disabling apps this way.                                   
2802             int messageId = R.string.uninstall_system_app_text;                                          
2803             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2804             return false;                                                                                
2805         } else {                                                                                         
2806             String packageName = componentName.getPackageName();                                         
2807             String className = componentName.getClassName();                                             
2808             Intent intent = new Intent(                                                                  
2809                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2810             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2811                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2812             if (user != null) {                                                                          
2813                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2814             }                                                                                            
2815             startActivity(intent);                                                                       
2816             return true;                                                                                 
2817         }                                                                                                
2818     }                                                                                                    
2819                                                                                                          
2820     boolean startActivity(View v, Intent intent, Object tag) {                                           
2821         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2822         try {                                                                                            
2823             // Only launch using the new animation if the shortcut has not opted out (this is a          
2824             // private contract between launcher and may be ignored in the future).                      
2825             boolean useLaunchAnimation = (v != null) &&                                                  
2826                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2827             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2828             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2829                                                                                                          
2830             UserHandleCompat user = null;                                                                
2831             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2832                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2833                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2834             }                                                                                            
2835                                                                                                          
2836             Bundle optsBundle = null;                                                                    
2837             if (useLaunchAnimation) {                                                                    
2838                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2839                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2840                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2841                 optsBundle = opts.toBundle();                                                            
2842             }                                                                                            
2843                                                                                                          
2844             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2845                 // Could be launching some bookkeeping activity                                          
2846                 startActivity(intent, optsBundle);                                                       
2847             } else {                                                                                     
2848                 // TODO Component can be null when shortcuts are supported for secondary user            
2849                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2850                         intent.getSourceBounds(), optsBundle);                                           
2851             }                                                                                            
2852             return true;                                                                                 
2853         } catch (SecurityException e) {                                                                  
2854             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2855             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2856                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2857                     "or use the exported attribute for this activity. "                                  
2858                     + "tag="+ tag + " intent=" + intent, e);                                             
2859         }                                                                                                
2860         return false;                                                                                    
2861     }                                                                                                    
2862                                                                                                          
2863     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2864         boolean success = false;                                                                         
2865         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2866             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2867             return false;                                                                                
2868         }                                                                                                
2869         try {                                                                                            
2870             success = startActivity(v, intent, tag);                                                     
2871         } catch (ActivityNotFoundException e) {                                                          
2872             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2873             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2874         }                                                                                                
2875         return success;                                                                                  
2876     }                                                                                                    
2877                                                                                                          
2878     /**                                                                                                  
2879      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2880      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2881      */                                                                                                  
2882     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2883         final int width = fi.getMeasuredWidth();                                                         
2884         final int height = fi.getMeasuredHeight();                                                       
2885                                                                                                          
2886         // Lazy load ImageView, Bitmap and Canvas                                                        
2887         if (mFolderIconImageView == null) {                                                              
2888             mFolderIconImageView = new ImageView(this);                                                  
2889         }                                                                                                
2890         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2891                 mFolderIconBitmap.getHeight() != height) {                                               
2892             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2893             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2894         }                                                                                                
2895                                                                                                          
2896         DragLayer.LayoutParams lp;                                                                       
2897         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2898             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2899         } else {                                                                                         
2900             lp = new DragLayer.LayoutParams(width, height);                                              
2901         }                                                                                                
2902                                                                                                          
2903         // The layout from which the folder is being opened may be scaled, adjust the starting           
2904         // view size by this scale factor.                                                               
2905         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2906         lp.customPosition = true;                                                                        
2907         lp.x = mRectForFolderAnimation.left;                                                             
2908         lp.y = mRectForFolderAnimation.top;                                                              
2909         lp.width = (int) (scale * width);                                                                
2910         lp.height = (int) (scale * height);                                                              
2911                                                                                                          
2912         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
2913         fi.draw(mFolderIconCanvas);                                                                      
2914         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
2915         if (fi.getFolder() != null) {                                                                    
2916             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
2917             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
2918         }                                                                                                
2919         // Just in case this image view is still in the drag layer from a previous animation,            
2920         // we remove it and re-add it.                                                                   
2921         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
2922             mDragLayer.removeView(mFolderIconImageView);                                                 
2923         }                                                                                                
2924         mDragLayer.addView(mFolderIconImageView, lp);                                                    
2925         if (fi.getFolder() != null) {                                                                    
2926             fi.getFolder().bringToFront();                                                               
2927         }                                                                                                
2928     }                                                                                                    
2929                                                                                                          
2930     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
2931         if (fi == null) return;                                                                          
2932         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
2933         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
2934         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
2935                                                                                                          
2936         FolderInfo info = (FolderInfo) fi.getTag();                                                      
2937         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
2938             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
2939             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
2940             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
2941         }                                                                                                
2942                                                                                                          
2943         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
2944         copyFolderIconToImage(fi);                                                                       
2945         fi.setVisibility(View.INVISIBLE);                                                                
2946                                                                                                          
2947         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
2948                 scaleX, scaleY);                                                                         
2949         if (Utilities.isLmpOrAbove()) {                                                                  
2950             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
2951         }                                                                                                
2952         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2953         oa.start();                                                                                      
2954     }                                                                                                    
2955                                                                                                          
2956     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
2957         if (fi == null) return;                                                                          
2958         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
2959         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
2960         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
2961                                                                                                          
2962         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
2963                                                                                                          
2964         // We remove and re-draw the FolderIcon in-case it has changed                                   
2965         mDragLayer.removeView(mFolderIconImageView);                                                     
2966         copyFolderIconToImage(fi);                                                                       
2967         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
2968                 scaleX, scaleY);                                                                         
2969         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2970         oa.addListener(new AnimatorListenerAdapter() {                                                   
2971             @Override                                                                                    
2972             public void onAnimationEnd(Animator animation) {                                             
2973                 if (cl != null) {                                                                        
2974                     cl.clearFolderLeaveBehind();                                                         
2975                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
2976                     mDragLayer.removeView(mFolderIconImageView);                                         
2977                     fi.setVisibility(View.VISIBLE);                                                      
2978                 }                                                                                        
2979             }                                                                                            
2980         });                                                                                              
2981         oa.start();                                                                                      
2982     }                                                                                                    
2983                                                                                                          
2984     /**                                                                                                  
2985      * Opens the user folder described by the specified tag. The opening of the folder                   
2986      * is animated relative to the specified View. If the View is null, no animation                     
2987      * is played.                                                                                        
2988      *                                                                                                   
2989      * @param folderInfo The FolderInfo describing the folder to open.                                   
2990      */                                                                                                  
2991     public void openFolder(FolderIcon folderIcon) {                                                      
2992         Folder folder = folderIcon.getFolder();                                                          
2993         FolderInfo info = folder.mInfo;                                                                  
2994                                                                                                          
2995         info.opened = true;                                                                              
2996                                                                                                          
2997         // Just verify that the folder hasn't already been added to the DragLayer.                       
2998         // There was a one-off crash where the folder had a parent already.                              
2999         if (folder.getParent() == null) {                                                                
3000             mDragLayer.addView(folder);                                                                  
3001             mDragController.addDropTarget((DropTarget) folder);                                          
3002         } else {                                                                                         
3003             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3004                     folder.getParent() + ").");                                                          
3005         }                                                                                                
3006         folder.animateOpen();                                                                            
3007         growAndFadeOutFolderIcon(folderIcon);                                                            
3008                                                                                                          
3009         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3010         // the workspace items                                                                           
3011         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3012         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3013     }                                                                                                    
3014                                                                                                          
3015     public void closeFolder() {                                                                          
3016         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3017         if (folder != null) {                                                                            
3018             if (folder.isEditingName()) {                                                                
3019                 folder.dismissEditingName();                                                             
3020             }                                                                                            
3021             closeFolder(folder);                                                                         
3022         }                                                                                                
3023     }                                                                                                    
3024                                                                                                          
3025     void closeFolder(Folder folder) {                                                                    
3026         folder.getInfo().opened = false;                                                                 
3027                                                                                                          
3028         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3029         if (parent != null) {                                                                            
3030             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3031             shrinkAndFadeInFolderIcon(fi);                                                               
3032         }                                                                                                
3033         folder.animateClosed();                                                                          
3034                                                                                                          
3035         // Notify the accessibility manager that this folder "window" has disappeard and no              
3036         // longer occludeds the workspace items                                                          
3037         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3038     }                                                                                                    
3039                                                                                                          
3040     public boolean onLongClick(View v) {                                                                 
3041         if (!isDraggingEnabled()) return false;                                                          
3042         if (isWorkspaceLocked()) return false;                                                           
3043         if (mState != State.WORKSPACE) return false;                                                     
3044                                                                                                          
3045         if (v instanceof Workspace) {                                                                    
3046             if (!mWorkspace.isInOverviewMode()) {                                                        
3047                 if (mWorkspace.enterOverviewMode()) {                                                    
3048                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3049                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3050                     return true;                                                                         
3051                 } else {                                                                                 
3052                     return false;                                                                        
3053                 }                                                                                        
3054             } else {                                                                                     
3055                 return false;                                                                            
3056             }                                                                                            
3057         }                                                                                                
3058                                                                                                          
3059         CellLayout.CellInfo longClickCellInfo = null;                                                    
3060         View itemUnderLongClick = null;                                                                  
3061         if (v.getTag() instanceof ItemInfo) {                                                            
3062             ItemInfo info = (ItemInfo) v.getTag();                                                       
3063             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3064             itemUnderLongClick = longClickCellInfo.cell;                                                 
3065             resetAddInfo();                                                                              
3066         }                                                                                                
3067                                                                                                          
3068         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3069         // on hotseat items.                                                                             
3070         final boolean inHotseat = isHotseatLayout(v);                                                    
3071         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3072         if (allowLongPress && !mDragController.isDragging()) {                                           
3073             if (itemUnderLongClick == null) {                                                            
3074                 // User long pressed on empty space                                                      
3075                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3076                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3077                 if (mWorkspace.isInOverviewMode()) {                                                     
3078                     mWorkspace.startReordering(v);                                                       
3079                 } else {                                                                                 
3080                     mWorkspace.enterOverviewMode();                                                      
3081                 }                                                                                        
3082             } else {                                                                                     
3083                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3084                         mHotseat.getOrderInHotseat(                                                      
3085                                 longClickCellInfo.cellX,                                                 
3086                                 longClickCellInfo.cellY));                                               
3087                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3088                     // User long pressed on an item                                                      
3089                     mWorkspace.startDrag(longClickCellInfo);                                             
3090                 }                                                                                        
3091             }                                                                                            
3092         }                                                                                                
3093         return true;                                                                                     
3094     }                                                                                                    
3095                                                                                                          
3096     boolean isHotseatLayout(View layout) {                                                               
3097         return mHotseat != null && layout != null &&                                                     
3098                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3099     }                                                                                                    
3100                                                                                                          
3101     /**                                                                                                  
3102      * Returns the CellLayout of the specified container at the specified screen.                        
3103      */                                                                                                  
3104     CellLayout getCellLayout(long container, long screenId) {                                            
3105         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3106             if (mHotseat != null) {                                                                      
3107                 return mHotseat.getLayout();                                                             
3108             } else {                                                                                     
3109                 return null;                                                                             
3110             }                                                                                            
3111         } else {                                                                                         
3112             return (CellLayout) mWorkspace.getScreenWithId(screenId);                                    
3113         }                                                                                                
3114     }                                                                                                    
3115                                                                                                          
3116     public boolean isAllAppsVisible() {                                                                  
3117         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);             
3118     }                                                                                                    
3119                                                                                                          
3120     private void setWorkspaceBackground(boolean workspace) {                                             
3121         mLauncherView.setBackground(workspace ?                                                          
3122                 mWorkspaceBackgroundDrawable : null);                                                    
3123     }                                                                                                    
3124                                                                                                          
3125     protected void changeWallpaperVisiblity(boolean visible) {                                           
3126         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3127         int curflags = getWindow().getAttributes().flags                                                 
3128                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3129         if (wpflags != curflags) {                                                                       
3130             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3131         }                                                                                                
3132         setWorkspaceBackground(visible);                                                                 
3133     }                                                                                                    
3134                                                                                                          
3135     private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {    
3136         if (v instanceof LauncherTransitionable) {                                                       
3137             ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);       
3138         }                                                                                                
3139     }                                                                                                    
3140                                                                                                          
3141     private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {      
3142         if (v instanceof LauncherTransitionable) {                                                       
3143             ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);         
3144         }                                                                                                
3145                                                                                                          
3146         // Update the workspace transition step as well                                                  
3147         dispatchOnLauncherTransitionStep(v, 0f);                                                         
3148     }                                                                                                    
3149                                                                                                          
3150     private void dispatchOnLauncherTransitionStep(View v, float t) {                                     
3151         if (v instanceof LauncherTransitionable) {                                                       
3152             ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                              
3153         }                                                                                                
3154     }                                                                                                    
3155                                                                                                          
3156     private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {        
3157         if (v instanceof LauncherTransitionable) {                                                       
3158             ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);           
3159         }                                                                                                
3160                                                                                                          
3161         // Update the workspace transition step as well                                                  
3162         dispatchOnLauncherTransitionStep(v, 1f);                                                         
3163     }                                                                                                    
3164                                                                                                          
3165     /**                                                                                                  
3166      * Things to test when changing the following seven functions.                                       
3167      *   - Home from workspace                                                                           
3168      *          - from center screen                                                                     
3169      *          - from other screens                                                                     
3170      *   - Home from all apps                                                                            
3171      *          - from center screen                                                                     
3172      *          - from other screens                                                                     
3173      *   - Back from all apps                                                                            
3174      *          - from center screen                                                                     
3175      *          - from other screens                                                                     
3176      *   - Launch app from workspace and quit                                                            
3177      *          - with back                                                                              
3178      *          - with home                                                                              
3179      *   - Launch app from all apps and quit                                                             
3180      *          - with back                                                                              
3181      *          - with home                                                                              
3182      *   - Go to a screen that's not the default, then all                                               
3183      *     apps, and launch and app, and go back                                                         
3184      *          - with back                                                                              
3185      *          -with home                                                                               
3186      *   - On workspace, long press power and go back                                                    
3187      *          - with back                                                                              
3188      *          - with home                                                                              
3189      *   - On all apps, long press power and go back                                                     
3190      *          - with back                                                                              
3191      *          - with home                                                                              
3192      *   - On workspace, power off                                                                       
3193      *   - On all apps, power off                                                                        
3194      *   - Launch an app and turn off the screen while in that app                                       
3195      *          - Go back with home key                                                                  
3196      *          - Go back with back key  TODO: make this not go to workspace                             
3197      *          - From all apps                                                                          
3198      *          - From workspace                                                                         
3199      *   - Enter and exit car mode (becuase it causes an extra configuration changed)                    
3200      *          - From all apps                                                                          
3201      *          - From the center workspace                                                              
3202      *          - From another workspace                                                                 
3203      */                                                                                                  
3204                                                                                                          
3205     /**                                                                                                  
3206      * Zoom the camera out from the workspace to reveal 'toView'.                                        
3207      * Assumes that the view to show is anchored at either the very top or very bottom                   
3208      * of the screen.                                                                                    
3209      */                                                                                                  
3210     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {           
3211         AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();         
3212         showAppsCustomizeHelper(animated, springLoaded, contentType);                                    
3213     }                                                                                                    
3214                                                                                                          
3215     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,             
3216                                          final AppsCustomizePagedView.ContentType contentType) {         
3217         if (mStateAnimation != null) {                                                                   
3218             mStateAnimation.setDuration(0);                                                              
3219             mStateAnimation.cancel();                                                                    
3220             mStateAnimation = null;                                                                      
3221         }                                                                                                
3222                                                                                                          
3223         boolean material = Utilities.isLmpOrAbove();                                                     
3224                                                                                                          
3225         final Resources res = getResources();                                                            
3226                                                                                                          
3227         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                   
3228         final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);               
3229         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);             
3230         final int itemsAlphaStagger =                                                                    
3231                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3232                                                                                                          
3233         final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);       
3234         final View fromView = mWorkspace;                                                                
3235         final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                       
3236                                                                                                          
3237         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3238                                                                                                          
3239         Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?     
3240                 Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                         
3241         Animator workspaceAnim =                                                                         
3242                 mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                
3243         if (!LauncherAppState.isDisableAllApps()                                                         
3244                 || contentType == AppsCustomizePagedView.ContentType.Widgets) {                          
3245             // Set the content type for the all apps/widgets space                                       
3246             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                  
3247         }                                                                                                
3248                                                                                                          
3249         // If for some reason our views aren't initialized, don't animate                                
3250         boolean initialized = getAllAppsButton() != null;                                                
3251                                                                                                          
3252         if (animated && initialized) {                                                                   
3253             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3254             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3255                     toView.findViewById(R.id.apps_customize_pane_content);                               
3256                                                                                                          
3257             final View page = content.getPageAt(content.getCurrentPage());                               
3258             final View revealView = toView.findViewById(R.id.fake_page);                                 
3259                                                                                                          
3260             final float initialPanelAlpha = 1f;                                                          
3261                                                                                                          
3262             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;      
3263             if (isWidgetTray) {                                                                          
3264                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                
3265             } else {                                                                                     
3266                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                     
3267             }                                                                                            
3268                                                                                                          
3269             // Hide the real page background, and swap in the fake one                                   
3270             content.setPageBackgroundsVisible(false);                                                    
3271             revealView.setVisibility(View.VISIBLE);                                                      
3272             // We need to hide this view as the animation start will be posted.                          
3273             revealView.setAlpha(0);                                                                      
3274                                                                                                          
3275             int width = revealView.getMeasuredWidth();                                                   
3276             int height = revealView.getMeasuredHeight();                                                 
3277             float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);         
3278                                                                                                          
3279             revealView.setTranslationY(0);                                                               
3280             revealView.setTranslationX(0);                                                               
3281                                                                                                          
3282             // Get the y delta between the center of the page and the center of the all apps button      
3283             int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                
3284                     getAllAppsButton(), null);                                                           
3285                                                                                                          
3286             float alpha = 0;                                                                             
3287             float xDrift = 0;                                                                            
3288             float yDrift = 0;                                                                            
3289             if (material) {                                                                              
3290                 alpha = isWidgetTray ? 0.3f : 1f;                                                        
3291                 yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                             
3292                 xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                      
3293             } else {                                                                                     
3294                 yDrift = 2 * height / 3;                                                                 
3295                 xDrift = 0;                                                                              
3296             }                                                                                            
3297             final float initAlpha = alpha;                                                               
3298                                                                                                          
3299             revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                     
3300             layerViews.add(revealView);                                                                  
3301             PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);      
3302             PropertyValuesHolder panelDriftY =                                                           
3303                     PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                             
3304             PropertyValuesHolder panelDriftX =                                                           
3305                     PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                             
3306                                                                                                          
3307             ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,        
3308                     panelAlpha, panelDriftY, panelDriftX);                                               
3309                                                                                                          
3310             panelAlphaAndDrift.setDuration(revealDuration);                                              
3311             panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                   
3312                                                                                                          
3313             mStateAnimation.play(panelAlphaAndDrift);                                                    
3314                                                                                                          
3315             if (page != null) {                                                                          
3316                 page.setVisibility(View.VISIBLE);                                                        
3317                 page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3318                 layerViews.add(page);                                                                    
3319                                                                                                          
3320                 ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);      
3321                 page.setTranslationY(yDrift);                                                            
3322                 pageDrift.setDuration(revealDuration);                                                   
3323                 pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                        
3324                 pageDrift.setStartDelay(itemsAlphaStagger);                                              
3325                 mStateAnimation.play(pageDrift);                                                         
3326                                                                                                          
3327                 page.setAlpha(0f);                                                                       
3328                 ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);               
3329                 itemsAlpha.setDuration(revealDuration);                                                  
3330                 itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                            
3331                 itemsAlpha.setStartDelay(itemsAlphaStagger);                                             
3332                 mStateAnimation.play(itemsAlpha);                                                        
3333             }                                                                                            
3334                                                                                                          
3335             View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);               
3336             pageIndicators.setAlpha(0.01f);                                                              
3337             ObjectAnimator indicatorsAlpha =                                                             
3338                     ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                 
3339             indicatorsAlpha.setDuration(revealDuration);                                                 
3340             mStateAnimation.play(indicatorsAlpha);                                                       
3341                                                                                                          
3342             if (material) {                                                                              
3343                 final View allApps = getAllAppsButton();                                                 
3344                 int allAppsButtonSize = LauncherAppState.getInstance().                                  
3345                         getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                     
3346                 float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                            
3347                 Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,         
3348                                 height / 2, startRadius, revealRadius);                                  
3349                 reveal.setDuration(revealDuration);                                                      
3350                 reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                           
3351                                                                                                          
3352                 reveal.addListener(new AnimatorListenerAdapter() {                                       
3353                     public void onAnimationStart(Animator animation) {                                   
3354                         if (!isWidgetTray) {                                                             
3355                             allApps.setVisibility(View.INVISIBLE);                                       
3356                         }                                                                                
3357                     }                                                                                    
3358                     public void onAnimationEnd(Animator animation) {                                     
3359                         if (!isWidgetTray) {                                                             
3360                             allApps.setVisibility(View.VISIBLE);                                         
3361                         }                                                                                
3362                     }                                                                                    
3363                 });                                                                                      
3364                 mStateAnimation.play(reveal);                                                            
3365             }                                                                                            
3366                                                                                                          
3367             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3368                 @Override                                                                                
3369                 public void onAnimationEnd(Animator animation) {                                         
3370                     dispatchOnLauncherTransitionEnd(fromView, animated, false);                          
3371                     dispatchOnLauncherTransitionEnd(toView, animated, false);                            
3372                                                                                                          
3373                     revealView.setVisibility(View.INVISIBLE);                                            
3374                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3375                     if (page != null) {                                                                  
3376                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3377                     }                                                                                    
3378                     content.setPageBackgroundsVisible(true);                                             
3379                                                                                                          
3380                     // Hide the search bar                                                               
3381                     if (mSearchDropTargetBar != null) {                                                  
3382                         mSearchDropTargetBar.hideSearchBar(false);                                       
3383                     }                                                                                    
3384                 }                                                                                        
3385                                                                                                          
3386             });                                                                                          
3387                                                                                                          
3388             if (workspaceAnim != null) {                                                                 
3389                 mStateAnimation.play(workspaceAnim);                                                     
3390             }                                                                                            
3391                                                                                                          
3392             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3393             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3394             final AnimatorSet stateAnimation = mStateAnimation;                                          
3395             final Runnable startAnimRunnable = new Runnable() {                                          
3396                 public void run() {                                                                      
3397                     // Check that mStateAnimation hasn't changed while                                   
3398                     // we waited for a layout/draw pass                                                  
3399                     if (mStateAnimation != stateAnimation)                                               
3400                         return;                                                                          
3401                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3402                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3403                                                                                                          
3404                     revealView.setAlpha(initAlpha);                                                      
3405                     if (Utilities.isLmpOrAbove()) {                                                      
3406                         for (int i = 0; i < layerViews.size(); i++) {                                    
3407                             View v = layerViews.get(i);                                                  
3408                             if (v != null) {                                                             
3409                                 boolean attached = true;                                                 
3410                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3411                                     attached = v.isAttachedToWindow();                                   
3412                                 }                                                                        
3413                                 if (attached) v.buildLayer();                                            
3414                             }                                                                            
3415                         }                                                                                
3416                     }                                                                                    
3417                     mStateAnimation.start();                                                             
3418                 }                                                                                        
3419             };                                                                                           
3420             toView.bringToFront();                                                                       
3421             toView.setVisibility(View.VISIBLE);                                                          
3422             toView.post(startAnimRunnable);                                                              
3423         } else {                                                                                         
3424             toView.setTranslationX(0.0f);                                                                
3425             toView.setTranslationY(0.0f);                                                                
3426             toView.setScaleX(1.0f);                                                                      
3427             toView.setScaleY(1.0f);                                                                      
3428             toView.setVisibility(View.VISIBLE);                                                          
3429             toView.bringToFront();                                                                       
3430                                                                                                          
3431             if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                      
3432                 // Hide the search bar                                                                   
3433                 if (mSearchDropTargetBar != null) {                                                      
3434                     mSearchDropTargetBar.hideSearchBar(false);                                           
3435                 }                                                                                        
3436             }                                                                                            
3437             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3438             dispatchOnLauncherTransitionStart(fromView, animated, false);                                
3439             dispatchOnLauncherTransitionEnd(fromView, animated, false);                                  
3440             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3441             dispatchOnLauncherTransitionStart(toView, animated, false);                                  
3442             dispatchOnLauncherTransitionEnd(toView, animated, false);                                    
3443         }                                                                                                
3444     }                                                                                                    
3445                                                                                                          
3446     /**                                                                                                  
3447      * Zoom the camera back into the workspace, hiding 'fromView'.                                       
3448      * This is the opposite of showAppsCustomizeHelper.                                                  
3449      * @param animated If true, the transition will be animated.                                         
3450      */                                                                                                  
3451     private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                
3452             final boolean springLoaded, final Runnable onCompleteRunnable) {                             
3453                                                                                                          
3454         if (mStateAnimation != null) {                                                                   
3455             mStateAnimation.setDuration(0);                                                              
3456             mStateAnimation.cancel();                                                                    
3457             mStateAnimation = null;                                                                      
3458         }                                                                                                
3459                                                                                                          
3460         boolean material = Utilities.isLmpOrAbove();                                                     
3461         Resources res = getResources();                                                                  
3462                                                                                                          
3463         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                  
3464         final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);           
3465         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);            
3466         final int itemsAlphaStagger =                                                                    
3467                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3468                                                                                                          
3469         final float scaleFactor = (float)                                                                
3470                 res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                           
3471         final View fromView = mAppsCustomizeTabHost;                                                     
3472         final View toView = mWorkspace;                                                                  
3473         Animator workspaceAnim = null;                                                                   
3474         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3475                                                                                                          
3476         if (toState == Workspace.State.NORMAL) {                                                         
3477             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3478                     toState, animated, layerViews);                                                      
3479         } else if (toState == Workspace.State.SPRING_LOADED ||                                           
3480                 toState == Workspace.State.OVERVIEW) {                                                   
3481             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3482                     toState, animated, layerViews);                                                      
3483         }                                                                                                
3484                                                                                                          
3485         // If for some reason our views aren't initialized, don't animate                                
3486         boolean initialized = getAllAppsButton() != null;                                                
3487                                                                                                          
3488         if (animated && initialized) {                                                                   
3489             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3490             if (workspaceAnim != null) {                                                                 
3491                 mStateAnimation.play(workspaceAnim);                                                     
3492             }                                                                                            
3493                                                                                                          
3494             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3495                     fromView.findViewById(R.id.apps_customize_pane_content);                             
3496                                                                                                          
3497             final View page = content.getPageAt(content.getNextPage());                                  
3498                                                                                                          
3499             // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases        
3500             int count = content.getChildCount();                                                         
3501             for (int i = 0; i < count; i++) {                                                            
3502                 View child = content.getChildAt(i);                                                      
3503                 if (child != page) {                                                                     
3504                     child.setVisibility(View.INVISIBLE);                                                 
3505                 }                                                                                        
3506             }                                                                                            
3507             final View revealView = fromView.findViewById(R.id.fake_page);                               
3508                                                                                                          
3509             // hideAppsCustomizeHelper is called in some cases when it is already hidden                 
3510             // don't perform all these no-op animations. In particularly, this was causing               
3511             // the all-apps button to pop in and out.                                                    
3512             if (fromView.getVisibility() == View.VISIBLE) {                                              
3513                 AppsCustomizePagedView.ContentType contentType = content.getContentType();               
3514                 final boolean isWidgetTray =                                                             
3515                         contentType == AppsCustomizePagedView.ContentType.Widgets;                       
3516                                                                                                          
3517                 if (isWidgetTray) {                                                                      
3518                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));            
3519                 } else {                                                                                 
3520                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                 
3521                 }                                                                                        
3522                                                                                                          
3523                 int width = revealView.getMeasuredWidth();                                               
3524                 int height = revealView.getMeasuredHeight();                                             
3525                 float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);     
3526                                                                                                          
3527                 // Hide the real page background, and swap in the fake one                               
3528                 revealView.setVisibility(View.VISIBLE);                                                  
3529                 content.setPageBackgroundsVisible(false);                                                
3530                                                                                                          
3531                 final View allAppsButton = getAllAppsButton();                                           
3532                 revealView.setTranslationY(0);                                                           
3533                 int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,            
3534                         allAppsButton, null);                                                            
3535                                                                                                          
3536                 float xDrift = 0;                                                                        
3537                 float yDrift = 0;                                                                        
3538                 if (material) {                                                                          
3539                     yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                         
3540                     xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                  
3541                 } else {                                                                                 
3542                     yDrift = 5 * height / 4;                                                             
3543                     xDrift = 0;                                                                          
3544                 }                                                                                        
3545                                                                                                          
3546                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                 
3547                 TimeInterpolator decelerateInterpolator = material ?                                     
3548                         new LogDecelerateInterpolator(100, 0) :                                          
3549                         new LogDecelerateInterpolator(30, 0);                                            
3550                                                                                                          
3551                 // The vertical motion of the apps panel should be delayed by one frame                  
3552                 // from the conceal animation in order to give the right feel. We correpsondingly        
3553                 // shorten the duration so that the slide and conceal end at the same time.              
3554                 ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",       
3555                         0, yDrift);                                                                      
3556                 panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3557                 panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3558                 panelDriftY.setInterpolator(decelerateInterpolator);                                     
3559                 mStateAnimation.play(panelDriftY);                                                       
3560                                                                                                          
3561                 ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",       
3562                         0, xDrift);                                                                      
3563                 panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3564                 panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3565                 panelDriftX.setInterpolator(decelerateInterpolator);                                     
3566                 mStateAnimation.play(panelDriftX);                                                       
3567                                                                                                          
3568                 if (isWidgetTray || !material) {                                                         
3569                     float finalAlpha = material ? 0.4f : 0f;                                             
3570                     revealView.setAlpha(1f);                                                             
3571                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",           
3572                             1f, finalAlpha);                                                             
3573                     panelAlpha.setDuration(revealDuration);                                              
3574                     panelAlpha.setInterpolator(material ? decelerateInterpolator :                       
3575                         new AccelerateInterpolator(1.5f));                                               
3576                     mStateAnimation.play(panelAlpha);                                                    
3577                 }                                                                                        
3578                                                                                                          
3579                 if (page != null) {                                                                      
3580                     page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                   
3581                                                                                                          
3582                     ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",           
3583                             0, yDrift);                                                                  
3584                     page.setTranslationY(0);                                                             
3585                     pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                          
3586                     pageDrift.setInterpolator(decelerateInterpolator);                                   
3587                     pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                     
3588                     mStateAnimation.play(pageDrift);                                                     
3589                                                                                                          
3590                     page.setAlpha(1f);                                                                   
3591                     ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);        
3592                     itemsAlpha.setDuration(100);                                                         
3593                     itemsAlpha.setInterpolator(decelerateInterpolator);                                  
3594                     mStateAnimation.play(itemsAlpha);                                                    
3595                 }                                                                                        
3596                                                                                                          
3597                 View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);         
3598                 pageIndicators.setAlpha(1f);                                                             
3599                 ObjectAnimator indicatorsAlpha =                                                         
3600                         LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                          
3601                 indicatorsAlpha.setDuration(revealDuration);                                             
3602                 indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                       
3603                 mStateAnimation.play(indicatorsAlpha);                                                   
3604                                                                                                          
3605                 width = revealView.getMeasuredWidth();                                                   
3606                                                                                                          
3607                 if (material) {                                                                          
3608                     if (!isWidgetTray) {                                                                 
3609                         allAppsButton.setVisibility(View.INVISIBLE);                                     
3610                     }                                                                                    
3611                     int allAppsButtonSize = LauncherAppState.getInstance().                              
3612                             getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                 
3613                     float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                        
3614                     Animator reveal =                                                                    
3615                             LauncherAnimUtils.createCircularReveal(revealView, width / 2,                
3616                                     height / 2, revealRadius, finalRadius);                              
3617                     reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                       
3618                     reveal.setDuration(revealDuration);                                                  
3619                     reveal.setStartDelay(itemsAlphaStagger);                                             
3620                                                                                                          
3621                     reveal.addListener(new AnimatorListenerAdapter() {                                   
3622                         public void onAnimationEnd(Animator animation) {                                 
3623                             revealView.setVisibility(View.INVISIBLE);                                    
3624                             if (!isWidgetTray) {                                                         
3625                                 allAppsButton.setVisibility(View.VISIBLE);                               
3626                             }                                                                            
3627                         }                                                                                
3628                     });                                                                                  
3629                                                                                                          
3630                     mStateAnimation.play(reveal);                                                        
3631                 }                                                                                        
3632                                                                                                          
3633                 dispatchOnLauncherTransitionPrepare(fromView, animated, true);                           
3634                 dispatchOnLauncherTransitionPrepare(toView, animated, true);                             
3635                 mAppsCustomizeContent.stopScrolling();                                                   
3636             }                                                                                            
3637                                                                                                          
3638             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3639                 @Override                                                                                
3640                 public void onAnimationEnd(Animator animation) {                                         
3641                     fromView.setVisibility(View.GONE);                                                   
3642                     dispatchOnLauncherTransitionEnd(fromView, animated, true);                           
3643                     dispatchOnLauncherTransitionEnd(toView, animated, true);                             
3644                     if (onCompleteRunnable != null) {                                                    
3645                         onCompleteRunnable.run();                                                        
3646                     }                                                                                    
3647                                                                                                          
3648                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3649                     if (page != null) {                                                                  
3650                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3651                     }                                                                                    
3652                     content.setPageBackgroundsVisible(true);                                             
3653                     // Unhide side pages                                                                 
3654                     int count = content.getChildCount();                                                 
3655                     for (int i = 0; i < count; i++) {                                                    
3656                         View child = content.getChildAt(i);                                              
3657                         child.setVisibility(View.VISIBLE);                                               
3658                     }                                                                                    
3659                                                                                                          
3660                     // Reset page transforms                                                             
3661                     if (page != null) {                                                                  
3662                         page.setTranslationX(0);                                                         
3663                         page.setTranslationY(0);                                                         
3664                         page.setAlpha(1);                                                                
3665                     }                                                                                    
3666                     content.setCurrentPage(content.getNextPage());                                       
3667                                                                                                          
3668                     mAppsCustomizeContent.updateCurrentPageScroll();                                     
3669                 }                                                                                        
3670             });                                                                                          
3671                                                                                                          
3672             final AnimatorSet stateAnimation = mStateAnimation;                                          
3673             final Runnable startAnimRunnable = new Runnable() {                                          
3674                 public void run() {                                                                      
3675                     // Check that mStateAnimation hasn't changed while                                   
3676                     // we waited for a layout/draw pass                                                  
3677                     if (mStateAnimation != stateAnimation)                                               
3678                         return;                                                                          
3679                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3680                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3681                                                                                                          
3682                     if (Utilities.isLmpOrAbove()) {                                                      
3683                         for (int i = 0; i < layerViews.size(); i++) {                                    
3684                             View v = layerViews.get(i);                                                  
3685                             if (v != null) {                                                             
3686                                 boolean attached = true;                                                 
3687                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3688                                     attached = v.isAttachedToWindow();                                   
3689                                 }                                                                        
3690                                 if (attached) v.buildLayer();                                            
3691                             }                                                                            
3692                         }                                                                                
3693                     }                                                                                    
3694                     mStateAnimation.start();                                                             
3695                 }                                                                                        
3696             };                                                                                           
3697             fromView.post(startAnimRunnable);                                                            
3698         } else {                                                                                         
3699             fromView.setVisibility(View.GONE);                                                           
3700             dispatchOnLauncherTransitionPrepare(fromView, animated, true);                               
3701             dispatchOnLauncherTransitionStart(fromView, animated, true);                                 
3702             dispatchOnLauncherTransitionEnd(fromView, animated, true);                                   
3703             dispatchOnLauncherTransitionPrepare(toView, animated, true);                                 
3704             dispatchOnLauncherTransitionStart(toView, animated, true);                                   
3705             dispatchOnLauncherTransitionEnd(toView, animated, true);                                     
3706         }                                                                                                
3707     }                                                                                                    
3708                                                                                                          
3709     @Override                                                                                            
3710     public void onTrimMemory(int level) {                                                                
3711         super.onTrimMemory(level);                                                                       
3712         if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                         
3713             mAppsCustomizeTabHost.onTrimMemory();                                                        
3714         }                                                                                                
3715     }                                                                                                    
3716                                                                                                          
3717     protected void showWorkspace(boolean animated) {                                                     
3718         showWorkspace(animated, null);                                                                   
3719     }                                                                                                    
3720                                                                                                          
3721     protected void showWorkspace() {                                                                     
3722         showWorkspace(true);                                                                             
3723     }                                                                                                    
3724                                                                                                          
3725     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3726         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3727             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3728             mWorkspace.setVisibility(View.VISIBLE);                                                      
3729             hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);        
3730                                                                                                          
3731             // Show the search bar (only animate if we were showing the drop target bar in spring        
3732             // loaded mode)                                                                              
3733             if (mSearchDropTargetBar != null) {                                                          
3734                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3735             }                                                                                            
3736                                                                                                          
3737             // Set focus to the AppsCustomize button                                                     
3738             if (mAllAppsButton != null) {                                                                
3739                 mAllAppsButton.requestFocus();                                                           
3740             }                                                                                            
3741         }                                                                                                
3742                                                                                                          
3743         // Change the state *after* we've called all the transition code                                 
3744         mState = State.WORKSPACE;                                                                        
3745                                                                                                          
3746         // Resume the auto-advance of widgets                                                            
3747         mUserPresent = true;                                                                             
3748         updateRunning();                                                                                 
3749                                                                                                          
3750         // Send an accessibility event to announce the context change                                    
3751         getWindow().getDecorView()                                                                       
3752                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3753                                                                                                          
3754         onWorkspaceShown(animated);                                                                      
3755     }                                                                                                    
3756                                                                                                          
3757     void showOverviewMode(boolean animated) {                                                            
3758         mWorkspace.setVisibility(View.VISIBLE);                                                          
3759         hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                        
3760         mState = State.WORKSPACE;                                                                        
3761         onWorkspaceShown(animated);                                                                      
3762     }                                                                                                    
3763                                                                                                          
3764     public void onWorkspaceShown(boolean animated) {                                                     
3765     }                                                                                                    
3766                                                                                                          
3767     void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                   
3768                      boolean resetPageToZero) {                                                          
3769         if (mState != State.WORKSPACE) return;                                                           
3770                                                                                                          
3771         if (resetPageToZero) {                                                                           
3772             mAppsCustomizeTabHost.reset();                                                               
3773         }                                                                                                
3774         showAppsCustomizeHelper(animated, false, contentType);                                           
3775         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3776             @Override                                                                                    
3777             public void run() {                                                                          
3778                 // We post this in-case the all apps view isn't yet constructed.                         
3779                 mAppsCustomizeTabHost.requestFocus();                                                    
3780             }                                                                                            
3781         });                                                                                              
3782                                                                                                          
3783         // Change the state *after* we've called all the transition code                                 
3784         mState = State.APPS_CUSTOMIZE;                                                                   
3785                                                                                                          
3786         // Pause the auto-advance of widgets until we are out of AllApps                                 
3787         mUserPresent = false;                                                                            
3788         updateRunning();                                                                                 
3789         closeFolder();                                                                                   
3790                                                                                                          
3791         // Send an accessibility event to announce the context change                                    
3792         getWindow().getDecorView()                                                                       
3793                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3794     }                                                                                                    
3795                                                                                                          
3796     void enterSpringLoadedDragMode() {                                                                   
3797         if (isAllAppsVisible()) {                                                                        
3798             hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                    
3799             mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                 
3800         }                                                                                                
3801     }                                                                                                    
3802                                                                                                          
3803     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3804             final Runnable onCompleteRunnable) {                                                         
3805         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                        
3806                                                                                                          
3807         mHandler.postDelayed(new Runnable() {                                                            
3808             @Override                                                                                    
3809             public void run() {                                                                          
3810                 if (successfulDrop) {                                                                    
3811                     // Before we show workspace, hide all apps again because                             
3812                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3813                     // clean up our state transition functions                                           
3814                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3815                     showWorkspace(true, onCompleteRunnable);                                             
3816                 } else {                                                                                 
3817                     exitSpringLoadedDragMode();                                                          
3818                 }                                                                                        
3819             }                                                                                            
3820         }, delay);                                                                                       
3821     }                                                                                                    
3822                                                                                                          
3823     void exitSpringLoadedDragMode() {                                                                    
3824         if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3825             final boolean animated = true;                                                               
3826             final boolean springLoaded = true;                                                           
3827             showAppsCustomizeHelper(animated, springLoaded);                                             
3828             mState = State.APPS_CUSTOMIZE;                                                               
3829         }                                                                                                
3830         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3831     }                                                                                                    
3832                                                                                                          
3833     void lockAllApps() {                                                                                 
3834         // TODO                                                                                          
3835     }                                                                                                    
3836                                                                                                          
3837     void unlockAllApps() {                                                                               
3838         // TODO                                                                                          
3839     }                                                                                                    
3840                                                                                                          
3841     /**                                                                                                  
3842      * Hides the hotseat area.                                                                           
3843      */                                                                                                  
3844     void hideHotseat(boolean animated) {                                                                 
3845         if (!LauncherAppState.getInstance().isScreenLarge()) {                                           
3846             if (animated) {                                                                              
3847                 if (mHotseat.getAlpha() != 0f) {                                                         
3848                     int duration = 0;                                                                    
3849                     if (mSearchDropTargetBar != null) {                                                  
3850                         duration = mSearchDropTargetBar.getTransitionOutDuration();                      
3851                     }                                                                                    
3852                     mHotseat.animate().alpha(0f).setDuration(duration);                                  
3853                 }                                                                                        
3854             } else {                                                                                     
3855                 mHotseat.setAlpha(0f);                                                                   
3856             }                                                                                            
3857         }                                                                                                
3858     }                                                                                                    
3859                                                                                                          
3860     /**                                                                                                  
3861      * Add an item from all apps or customize onto the given workspace screen.                           
3862      * If layout is null, add to the current screen.                                                     
3863      */                                                                                                  
3864     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                           
3865         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                     
3866             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
3867         }                                                                                                
3868     }                                                                                                    
3869                                                                                                          
3870     /** Maps the current orientation to an index for referencing orientation correct global icons */     
3871     private int getCurrentOrientationIndexForGlobalIcons() {                                             
3872         // default - 0, landscape - 1                                                                    
3873         switch (getResources().getConfiguration().orientation) {                                         
3874         case Configuration.ORIENTATION_LANDSCAPE:                                                        
3875             return 1;                                                                                    
3876         default:                                                                                         
3877             return 0;                                                                                    
3878         }                                                                                                
3879     }                                                                                                    
3880                                                                                                          
3881     private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {    
3882         try {                                                                                            
3883             PackageManager packageManager = getPackageManager();                                         
3884             // Look for the toolbar icon specified in the activity meta-data                             
3885             Bundle metaData = packageManager.getActivityInfo(                                            
3886                     activityName, PackageManager.GET_META_DATA).metaData;                                
3887             if (metaData != null) {                                                                      
3888                 int iconResId = metaData.getInt(resourceName);                                           
3889                 if (iconResId != 0) {                                                                    
3890                     Resources res = packageManager.getResourcesForActivity(activityName);                
3891                     return res.getDrawable(iconResId);                                                   
3892                 }                                                                                        
3893             }                                                                                            
3894         } catch (NameNotFoundException e) {                                                              
3895             // This can happen if the activity defines an invalid drawable                               
3896             Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +           
3897                     " not found", e);                                                                    
3898         } catch (Resources.NotFoundException nfe) {                                                      
3899             // This can happen if the activity defines an invalid drawable                               
3900             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),        
3901                     nfe);                                                                                
3902         }                                                                                                
3903         return null;                                                                                     
3904     }                                                                                                    
3905                                                                                                          
3906     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3907     private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                         
3908             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3909             String toolbarResourceName) {                                                                
3910         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3911         Resources r = getResources();                                                                    
3912         int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                            
3913         int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                           
3914                                                                                                          
3915         TextView button = (TextView) findViewById(buttonId);                                             
3916         // If we were unable to find the icon via the meta-data, use a generic one                       
3917         if (toolbarIcon == null) {                                                                       
3918             toolbarIcon = r.getDrawable(fallbackDrawableId);                                             
3919             toolbarIcon.setBounds(0, 0, w, h);                                                           
3920             if (button != null) {                                                                        
3921                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3922             }                                                                                            
3923             return null;                                                                                 
3924         } else {                                                                                         
3925             toolbarIcon.setBounds(0, 0, w, h);                                                           
3926             if (button != null) {                                                                        
3927                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3928             }                                                                                            
3929             return toolbarIcon.getConstantState();                                                       
3930         }                                                                                                
3931     }                                                                                                    
3932                                                                                                          
3933     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3934     private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                             
3935             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3936             String toolbarResourceName) {                                                                
3937         ImageView button = (ImageView) findViewById(buttonId);                                           
3938         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3939                                                                                                          
3940         if (button != null) {                                                                            
3941             // If we were unable to find the icon via the meta-data, use a                               
3942             // generic one                                                                               
3943             if (toolbarIcon == null) {                                                                   
3944                 button.setImageResource(fallbackDrawableId);                                             
3945             } else {                                                                                     
3946                 button.setImageDrawable(toolbarIcon);                                                    
3947             }                                                                                            
3948         }                                                                                                
3949                                                                                                          
3950         return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                              
3951                                                                                                          
3952     }                                                                                                    
3953                                                                                                          
3954     private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                
3955         TextView button = (TextView) findViewById(buttonId);                                             
3956         button.setCompoundDrawables(d, null, null, null);                                                
3957     }                                                                                                    
3958                                                                                                          
3959     private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                      
3960         ImageView button = (ImageView) findViewById(buttonId);                                           
3961         button.setImageDrawable(d.newDrawable(getResources()));                                          
3962     }                                                                                                    
3963                                                                                                          
3964     private void invalidatePressedFocusedStates(View container, View button) {                           
3965         if (container instanceof HolographicLinearLayout) {                                              
3966             HolographicLinearLayout layout = (HolographicLinearLayout) container;                        
3967             layout.invalidatePressedFocusedStates();                                                     
3968         } else if (button instanceof HolographicImageView) {                                             
3969             HolographicImageView view = (HolographicImageView) button;                                   
3970             view.invalidatePressedFocusedStates();                                                       
3971         }                                                                                                
3972     }                                                                                                    
3973                                                                                                          
3974     public View getQsbBar() {                                                                            
3975         if (mQsb == null) {                                                                              
3976             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                         
3977             mSearchDropTargetBar.addView(mQsb);                                                          
3978         }                                                                                                
3979         return mQsb;                                                                                     
3980     }                                                                                                    
3981                                                                                                          
3982     protected boolean updateGlobalSearchIcon() {                                                         
3983         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
3984         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                     
3985         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
3986         final View voiceButton = findViewById(R.id.voice_button);                                        
3987                                                                                                          
3988         final SearchManager searchManager =                                                              
3989                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
3990         ComponentName activityName = searchManager.getGlobalSearchActivity();                            
3991         if (activityName != null) {                                                                      
3992             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
3993             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                           
3994                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,             
3995                     TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                  
3996             if (sGlobalSearchIcon[coi] == null) {                                                        
3997                 sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                       
3998                         R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,         
3999                         TOOLBAR_ICON_METADATA_NAME);                                                     
4000             }                                                                                            
4001                                                                                                          
4002             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);        
4003             searchButton.setVisibility(View.VISIBLE);                                                    
4004             invalidatePressedFocusedStates(searchButtonContainer, searchButton);                         
4005             return true;                                                                                 
4006         } else {                                                                                         
4007             // We disable both search and voice search when there is no global search provider           
4008             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);           
4009             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4010             if (searchButton != null) searchButton.setVisibility(View.GONE);                             
4011             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4012             updateVoiceButtonProxyVisible(false);                                                        
4013             return false;                                                                                
4014         }                                                                                                
4015     }                                                                                                    
4016                                                                                                          
4017     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                    
4018         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4019         final View searchButton = (ImageView) findViewById(R.id.search_button);                          
4020         updateButtonWithDrawable(R.id.search_button, d);                                                 
4021         invalidatePressedFocusedStates(searchButtonContainer, searchButton);                             
4022     }                                                                                                    
4023                                                                                                          
4024     protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                     
4025         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4026         final View voiceButton = findViewById(R.id.voice_button);                                        
4027                                                                                                          
4028         // We only show/update the voice search icon if the search icon is enabled as well               
4029         final SearchManager searchManager =                                                              
4030                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4031         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
4032                                                                                                          
4033         ComponentName activityName = null;                                                               
4034         if (globalSearchActivity != null) {                                                              
4035             // Check if the global search activity handles voice search                                  
4036             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4037             intent.setPackage(globalSearchActivity.getPackageName());                                    
4038             activityName = intent.resolveActivity(getPackageManager());                                  
4039         }                                                                                                
4040                                                                                                          
4041         if (activityName == null) {                                                                      
4042             // Fallback: check if an activity other than the global search activity                      
4043             // resolves this                                                                             
4044             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4045             activityName = intent.resolveActivity(getPackageManager());                                  
4046         }                                                                                                
4047         if (searchVisible && activityName != null) {                                                     
4048             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4049             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                            
4050                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,               
4051                     TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                            
4052             if (sVoiceSearchIcon[coi] == null) {                                                         
4053                 sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                        
4054                         R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,           
4055                         TOOLBAR_ICON_METADATA_NAME);                                                     
4056             }                                                                                            
4057             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);          
4058             voiceButton.setVisibility(View.VISIBLE);                                                     
4059             updateVoiceButtonProxyVisible(false);                                                        
4060             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                           
4061             return true;                                                                                 
4062         } else {                                                                                         
4063             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4064             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4065             updateVoiceButtonProxyVisible(false);                                                        
4066             return false;                                                                                
4067         }                                                                                                
4068     }                                                                                                    
4069                                                                                                          
4070     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                     
4071         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4072         final View voiceButton = findViewById(R.id.voice_button);                                        
4073         updateButtonWithDrawable(R.id.voice_button, d);                                                  
4074         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                               
4075     }                                                                                                    
4076                                                                                                          
4077     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                    
4078         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                             
4079         if (voiceButtonProxy != null) {                                                                  
4080             boolean visible = !forceDisableVoiceButtonProxy &&                                           
4081                     mWorkspace.shouldVoiceButtonProxyBeVisible();                                        
4082             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                          
4083             voiceButtonProxy.bringToFront();                                                             
4084         }                                                                                                
4085     }                                                                                                    
4086                                                                                                          
4087     /**                                                                                                  
4088      * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button🔵
4089      * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                      
4090      */                                                                                                  
4091     public void disableVoiceButtonProxy(boolean disabled) {                                              
4092         updateVoiceButtonProxyVisible(disabled);                                                         
4093     }                                                                                                    
4094                                                                                                          
4095     @Override                                                                                            
4096     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
4097         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
4098         final List<CharSequence> text = event.getText();                                                 
4099         text.clear();                                                                                    
4100         // Populate event with a fake title based on the current state.                                  
4101         if (mState == State.APPS_CUSTOMIZE) {                                                            
4102             text.add(mAppsCustomizeTabHost.getContentTag());                                             
4103         } else {                                                                                         
4104             text.add(getString(R.string.all_apps_home_button_label));                                    
4105         }                                                                                                
4106         return result;                                                                                   
4107     }                                                                                                    
4108                                                                                                          
4109     /**                                                                                                  
4110      * Receives notifications when system dialogs are to be closed.                                      
4111      */                                                                                                  
4112     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
4113         @Override                                                                                        
4114         public void onReceive(Context context, Intent intent) {                                          
4115             closeSystemDialogs();                                                                        
4116         }                                                                                                
4117     }                                                                                                    
4118                                                                                                          
4119     /**                                                                                                  
4120      * Receives notifications whenever the appwidgets are reset.                                         
4121      */                                                                                                  
4122     private class AppWidgetResetObserver extends ContentObserver {                                       
4123         public AppWidgetResetObserver() {                                                                
4124             super(new Handler());                                                                        
4125         }                                                                                                
4126                                                                                                          
4127         @Override                                                                                        
4128         public void onChange(boolean selfChange) {                                                       
4129             onAppWidgetReset();                                                                          
4130         }                                                                                                
4131     }                                                                                                    
4132                                                                                                          
4133     /**                                                                                                  
4134      * If the activity is currently paused, signal that we need to run the passed Runnable               
4135      * in onResume.                                                                                      
4136      *                                                                                                   
4137      * This needs to be called from incoming places where resources might have been loaded               
4138      * while we are paused.  That is becaues the Configuration might be wrong                            
4139      * when we're not running, and if it comes back to what it was when we                               
4140      * were paused, we are not restarted.                                                                
4141      *                                                                                                   
4142      * Implementation of the method from LauncherModel.Callbacks.                                        
4143      *                                                                                                   
4144      * @return true if we are currently paused.  The caller might be able to                             
4145      * skip some work in that case since we will come back again.                                        
4146      */                                                                                                  
4147     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
4148         if (mPaused) {                                                                                   
4149             Log.i(TAG, "Deferring update until onResume");                                               
4150             if (deletePreviousRunnables) {                                                               
4151                 while (mBindOnResumeCallbacks.remove(run)) {                                             
4152                 }                                                                                        
4153             }                                                                                            
4154             mBindOnResumeCallbacks.add(run);                                                             
4155             return true;                                                                                 
4156         } else {                                                                                         
4157             return false;                                                                                
4158         }                                                                                                
4159     }                                                                                                    
4160                                                                                                          
4161     private boolean waitUntilResume(Runnable run) {                                                      
4162         return waitUntilResume(run, false);                                                              
4163     }                                                                                                    
4164                                                                                                          
4165     public void addOnResumeCallback(Runnable run) {                                                      
4166         mOnResumeCallbacks.add(run);                                                                     
4167     }                                                                                                    
4168                                                                                                          
4169     /**                                                                                                  
4170      * If the activity is currently paused, signal that we need to re-run the loader                     
4171      * in onResume.                                                                                      
4172      *                                                                                                   
4173      * This needs to be called from incoming places where resources might have been loaded               
4174      * while we are paused.  That is becaues the Configuration might be wrong                            
4175      * when we're not running, and if it comes back to what it was when we                               
4176      * were paused, we are not restarted.                                                                
4177      *                                                                                                   
4178      * Implementation of the method from LauncherModel.Callbacks.                                        
4179      *                                                                                                   
4180      * @return true if we are currently paused.  The caller might be able to                             
4181      * skip some work in that case since we will come back again.                                        
4182      */                                                                                                  
4183     public boolean setLoadOnResume() {                                                                   
4184         if (mPaused) {                                                                                   
4185             Log.i(TAG, "setLoadOnResume");                                                               
4186             mOnResumeNeedsLoad = true;                                                                   
4187             return true;                                                                                 
4188         } else {                                                                                         
4189             return false;                                                                                
4190         }                                                                                                
4191     }                                                                                                    
4192                                                                                                          
4193     /**                                                                                                  
4194      * Implementation of the method from LauncherModel.Callbacks.                                        
4195      */                                                                                                  
4196     public int getCurrentWorkspaceScreen() {                                                             
4197         if (mWorkspace != null) {                                                                        
4198             return mWorkspace.getCurrentPage();                                                          
4199         } else {                                                                                         
4200             return SCREEN_COUNT / 2;                                                                     
4201         }                                                                                                
4202     }                                                                                                    
4203                                                                                                          
4204     /**                                                                                                  
4205      * Refreshes the shortcuts shown on the workspace.                                                   
4206      *                                                                                                   
4207      * Implementation of the method from LauncherModel.Callbacks.                                        
4208      */                                                                                                  
4209     public void startBinding() {                                                                         
4210         setWorkspaceLoading(true);                                                                       
4211                                                                                                          
4212         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4213         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4214         // from scratch again                                                                            
4215         mBindOnResumeCallbacks.clear();                                                                  
4216                                                                                                          
4217         // Clear the workspace because it's going to be rebound                                          
4218         mWorkspace.clearDropTargets();                                                                   
4219         mWorkspace.removeAllWorkspaceScreens();                                                          
4220                                                                                                          
4221         mWidgetsToAdvance.clear();                                                                       
4222         if (mHotseat != null) {                                                                          
4223             mHotseat.resetLayout();                                                                      
4224         }                                                                                                
4225     }                                                                                                    
4226                                                                                                          
4227     @Override                                                                                            
4228     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4229         bindAddScreens(orderedScreenIds);                                                                
4230                                                                                                          
4231         // If there are no screens, we need to have an empty screen                                      
4232         if (orderedScreenIds.size() == 0) {                                                              
4233             mWorkspace.addExtraEmptyScreen();                                                            
4234         }                                                                                                
4235                                                                                                          
4236         // Create the custom content page (this call updates mDefaultScreen which calls                  
4237         // setCurrentPage() so ensure that all pages are added before calling this).                     
4238         if (hasCustomContentToLeft()) {                                                                  
4239             mWorkspace.createCustomContentContainer();                                                   
4240             populateCustomContentContainer();                                                            
4241         }                                                                                                
4242     }                                                                                                    
4243                                                                                                          
4244     @Override                                                                                            
4245     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4246         // Log to disk                                                                                   
4247         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4248         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4249                 TextUtils.join(", ", orderedScreenIds), true);                                           
4250         int count = orderedScreenIds.size();                                                             
4251         for (int i = 0; i < count; i++) {                                                                
4252             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4253         }                                                                                                
4254     }                                                                                                    
4255                                                                                                          
4256     private boolean shouldShowWeightWatcher() {                                                          
4257         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4258         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4259         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4260                                                                                                          
4261         return show;                                                                                     
4262     }                                                                                                    
4263                                                                                                          
4264     private void toggleShowWeightWatcher() {                                                             
4265         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4266         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4267         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4268                                                                                                          
4269         show = !show;                                                                                    
4270                                                                                                          
4271         SharedPreferences.Editor editor = sp.edit();                                                     
4272         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4273         editor.commit();                                                                                 
4274                                                                                                          
4275         if (mWeightWatcher != null) {                                                                    
4276             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4277         }                                                                                                
4278     }                                                                                                    
4279                                                                                                          
4280     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4281                               final ArrayList<ItemInfo> addNotAnimated,                                  
4282                               final ArrayList<ItemInfo> addAnimated,                                     
4283                               final ArrayList<AppInfo> addedApps) {                                      
4284         Runnable r = new Runnable() {                                                                    
4285             public void run() {                                                                          
4286                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4287             }                                                                                            
4288         };                                                                                               
4289         if (waitUntilResume(r)) {                                                                        
4290             return;                                                                                      
4291         }                                                                                                
4292                                                                                                          
4293         // Add the new screens                                                                           
4294         if (newScreens != null) {                                                                        
4295             bindAddScreens(newScreens);                                                                  
4296         }                                                                                                
4297                                                                                                          
4298         // We add the items without animation on non-visible pages, and with                             
4299         // animations on the new page (which we will try and snap to).                                   
4300         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
4301             bindItems(addNotAnimated, 0,                                                                 
4302                     addNotAnimated.size(), false);                                                       
4303         }                                                                                                
4304         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
4305             bindItems(addAnimated, 0,                                                                    
4306                     addAnimated.size(), true);                                                           
4307         }                                                                                                
4308                                                                                                          
4309         // Remove the extra empty screen                                                                 
4310         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4311                                                                                                          
4312         if (!LauncherAppState.isDisableAllApps() &&                                                      
4313                 addedApps != null && mAppsCustomizeContent != null) {                                    
4314             mAppsCustomizeContent.addApps(addedApps);                                                    
4315         }                                                                                                
4316     }                                                                                                    
4317                                                                                                          
4318     /**                                                                                                  
4319      * Bind the items start-end from the list.                                                           
4320      *                                                                                                   
4321      * Implementation of the method from LauncherModel.Callbacks.                                        
4322      */                                                                                                  
4323     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4324                           final boolean forceAnimateIcons) {                                             
4325         Runnable r = new Runnable() {                                                                    
4326             public void run() {                                                                          
4327                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4328             }                                                                                            
4329         };                                                                                               
4330         if (waitUntilResume(r)) {                                                                        
4331             return;                                                                                      
4332         }                                                                                                
4333                                                                                                          
4334         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4335         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4336         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4337         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4338         Workspace workspace = mWorkspace;                                                                
4339         long newShortcutsScreenId = -1;                                                                  
4340         for (int i = start; i < end; i++) {                                                              
4341             final ItemInfo item = shortcuts.get(i);                                                      
4342                                                                                                          
4343             // Short circuit if we are loading dock items for a configuration which has no dock          
4344             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4345                     mHotseat == null) {                                                                  
4346                 continue;                                                                                
4347             }                                                                                            
4348                                                                                                          
4349             switch (item.itemType) {                                                                     
4350                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4351                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4352                     ShortcutInfo info = (ShortcutInfo) item;                                             
4353                     View shortcut = createShortcut(info);                                                
4354                                                                                                          
4355                     /*                                                                                   
4356                      * TODO: FIX collision case                                                          
4357                      */                                                                                  
4358                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4359                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4360                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4361                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4362                             Object tag = v.getTag();                                                     
4363                             String desc = "Collision while binding workspace item: " + item              
4364                                     + ". Collides with " + tag;                                          
4365                             if (LauncherAppState.isDogfoodBuild()) {                                     
4366                                 throw (new RuntimeException(desc));                                      
4367                             } else {                                                                     
4368                                 Log.d(TAG, desc);                                                        
4369                             }                                                                            
4370                         }                                                                                
4371                     }                                                                                    
4372                                                                                                          
4373                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4374                             item.cellY, 1, 1);                                                           
4375                     if (animateIcons) {                                                                  
4376                         // Animate all the applications up now                                           
4377                         shortcut.setAlpha(0f);                                                           
4378                         shortcut.setScaleX(0f);                                                          
4379                         shortcut.setScaleY(0f);                                                          
4380                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4381                         newShortcutsScreenId = item.screenId;                                            
4382                     }                                                                                    
4383                     break;                                                                               
4384                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4385                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4386                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4387                             (FolderInfo) item, mIconCache);                                              
4388                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4389                             item.cellY, 1, 1);                                                           
4390                     break;                                                                               
4391                 default:                                                                                 
4392                     throw new RuntimeException("Invalid Item Type");                                     
4393             }                                                                                            
4394         }                                                                                                
4395                                                                                                          
4396         if (animateIcons) {                                                                              
4397             // Animate to the correct page                                                               
4398             if (newShortcutsScreenId > -1) {                                                             
4399                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4400                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4401                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4402                     public void run() {                                                                  
4403                         anim.playTogether(bounceAnims);                                                  
4404                         anim.start();                                                                    
4405                     }                                                                                    
4406                 };                                                                                       
4407                 if (newShortcutsScreenId != currentScreenId) {                                           
4408                     // We post the animation slightly delayed to prevent slowdowns                       
4409                     // when we are loading right after we return to launcher.                            
4410                     mWorkspace.postDelayed(new Runnable() {                                              
4411                         public void run() {                                                              
4412                             if (mWorkspace != null) {                                                    
4413                                 mWorkspace.snapToPage(newScreenIndex);                                   
4414                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4415                                         NEW_APPS_ANIMATION_DELAY);                                       
4416                             }                                                                            
4417                         }                                                                                
4418                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4419                 } else {                                                                                 
4420                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4421                 }                                                                                        
4422             }                                                                                            
4423         }                                                                                                
4424         workspace.requestLayout();                                                                       
4425     }                                                                                                    
4426                                                                                                          
4427     /**                                                                                                  
4428      * Implementation of the method from LauncherModel.Callbacks.                                        
4429      */                                                                                                  
4430     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4431         Runnable r = new Runnable() {                                                                    
4432             public void run() {                                                                          
4433                 bindFolders(folders);                                                                    
4434             }                                                                                            
4435         };                                                                                               
4436         if (waitUntilResume(r)) {                                                                        
4437             return;                                                                                      
4438         }                                                                                                
4439         sFolders.clear();                                                                                
4440         sFolders.putAll(folders);                                                                        
4441     }                                                                                                    
4442                                                                                                          
4443     /**                                                                                                  
4444      * Add the views for a widget to the workspace.                                                      
4445      *                                                                                                   
4446      * Implementation of the method from LauncherModel.Callbacks.                                        
4447      */                                                                                                  
4448     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4449         Runnable r = new Runnable() {                                                                    
4450             public void run() {                                                                          
4451                 bindAppWidget(item);                                                                     
4452             }                                                                                            
4453         };                                                                                               
4454         if (waitUntilResume(r)) {                                                                        
4455             return;                                                                                      
4456         }                                                                                                
4457                                                                                                          
4458         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4459         if (DEBUG_WIDGETS) {                                                                             
4460             Log.d(TAG, "bindAppWidget: " + item);                                                        
4461         }                                                                                                
4462         final Workspace workspace = mWorkspace;                                                          
4463                                                                                                          
4464         AppWidgetProviderInfo appWidgetInfo;                                                             
4465         if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&               
4466                 ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                 
4467                                                                                                          
4468             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);      
4469             if (appWidgetInfo == null) {                                                                 
4470                 if (DEBUG_WIDGETS) {                                                                     
4471                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4472                             + " belongs to component " + item.providerName                               
4473                             + ", as the povider is null");                                               
4474                 }                                                                                        
4475                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4476                 return;                                                                                  
4477             }                                                                                            
4478             // Note: This assumes that the id remap broadcast is received before this step.              
4479             // If that is not the case, the id remap will be ignored and user may see the                
4480             // click to setup view.                                                                      
4481             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);      
4482             pendingInfo.spanX = item.spanX;                                                              
4483             pendingInfo.spanY = item.spanY;                                                              
4484             pendingInfo.minSpanX = item.minSpanX;                                                        
4485             pendingInfo.minSpanY = item.minSpanY;                                                        
4486             Bundle options =                                                                             
4487                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
4488                                                                                                          
4489             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4490             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4491                     newWidgetId, appWidgetInfo, options);                                                
4492                                                                                                          
4493             // TODO consider showing a permission dialog when the widget is clicked.                     
4494             if (!success) {                                                                              
4495                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4496                 if (DEBUG_WIDGETS) {                                                                     
4497                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4498                             + " belongs to component " + item.providerName                               
4499                             + ", as the launcher is unable to bing a new widget id");                    
4500                 }                                                                                        
4501                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4502                 return;                                                                                  
4503             }                                                                                            
4504                                                                                                          
4505             item.appWidgetId = newWidgetId;                                                              
4506                                                                                                          
4507             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4508             // the widget is ready to go.                                                                
4509             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4510                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4511                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4512                                                                                                          
4513             LauncherModel.updateItemInDatabase(this, item);                                              
4514         }                                                                                                
4515                                                                                                          
4516         if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                             
4517             final int appWidgetId = item.appWidgetId;                                                    
4518             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
4519             if (DEBUG_WIDGETS) {                                                                         
4520                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidget🔵
4521             }                                                                                            
4522                                                                                                          
4523             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4524         } else {                                                                                         
4525             appWidgetInfo = null;                                                                        
4526             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                    
4527             view.updateIcon(mIconCache);                                                                 
4528             item.hostView = view;                                                                        
4529             item.hostView.updateAppWidget(null);                                                         
4530             item.hostView.setOnClickListener(this);                                                      
4531         }                                                                                                
4532                                                                                                          
4533         item.hostView.setTag(item);                                                                      
4534         item.onBindAppWidget(this);                                                                      
4535                                                                                                          
4536         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4537                 item.cellY, item.spanX, item.spanY, false);                                              
4538         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
4539                                                                                                          
4540         workspace.requestLayout();                                                                       
4541                                                                                                          
4542         if (DEBUG_WIDGETS) {                                                                             
4543             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4544                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4545         }                                                                                                
4546     }                                                                                                    
4547                                                                                                          
4548     /**                                                                                                  
4549      * Restores a pending widget.                                                                        
4550      *                                                                                                   
4551      * @param appWidgetId The app widget id                                                              
4552      * @param cellInfo The position on screen where to create the widget.                                
4553      */                                                                                                  
4554     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4555         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4556         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4557             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4558             return;                                                                                      
4559         }                                                                                                
4560                                                                                                          
4561         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4562         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4563                                                                                                          
4564         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4565         LauncherModel.updateItemInDatabase(this, info);                                                  
4566     }                                                                                                    
4567                                                                                                          
4568     public void onPageBoundSynchronously(int page) {                                                     
4569         mSynchronouslyBoundPages.add(page);                                                              
4570     }                                                                                                    
4571                                                                                                          
4572     /**                                                                                                  
4573      * Callback saying that there aren't any more items to bind.                                         
4574      *                                                                                                   
4575      * Implementation of the method from LauncherModel.Callbacks.                                        
4576      */                                                                                                  
4577     public void finishBindingItems(final boolean upgradePath) {                                          
4578         Runnable r = new Runnable() {                                                                    
4579             public void run() {                                                                          
4580                 finishBindingItems(upgradePath);                                                         
4581             }                                                                                            
4582         };                                                                                               
4583         if (waitUntilResume(r)) {                                                                        
4584             return;                                                                                      
4585         }                                                                                                
4586         if (mSavedState != null) {                                                                       
4587             if (!mWorkspace.hasFocus()) {                                                                
4588                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4589             }                                                                                            
4590             mSavedState = null;                                                                          
4591         }                                                                                                
4592                                                                                                          
4593         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4594                                                                                                          
4595         setWorkspaceLoading(false);                                                                      
4596         sendLoadingCompleteBroadcastIfNecessary();                                                       
4597                                                                                                          
4598         // If we received the result of any pending adds while the loader was running (e.g. the          
4599         // widget configuration forced an orientation change), process them now.                         
4600         if (sPendingAddItem != null) {                                                                   
4601             final long screenId = completeAdd(sPendingAddItem);                                          
4602                                                                                                          
4603             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4604             // the screen would be guaranteed to exist after bind, and the page would be set through     
4605             // the workspace restore process.                                                            
4606             mWorkspace.post(new Runnable() {                                                             
4607                 @Override                                                                                
4608                 public void run() {                                                                      
4609                     mWorkspace.snapToScreenId(screenId);                                                 
4610                 }                                                                                        
4611             });                                                                                          
4612             sPendingAddItem = null;                                                                      
4613         }                                                                                                
4614                                                                                                          
4615         if (upgradePath) {                                                                               
4616             mWorkspace.getUniqueComponents(true, null);                                                  
4617             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4618         }                                                                                                
4619         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4620         mModel.recheckRestoredItems(this);                                                               
4621     }                                                                                                    
4622                                                                                                          
4623     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4624         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4625             String permission =                                                                          
4626                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4627             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4628             sendBroadcast(intent, permission);                                                           
4629             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4630             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4631             editor.apply();                                                                              
4632         }                                                                                                
4633     }                                                                                                    
4634                                                                                                          
4635     public boolean isAllAppsButtonRank(int rank) {                                                       
4636         if (mHotseat != null) {                                                                          
4637             return mHotseat.isAllAppsButtonRank(rank);                                                   
4638         }                                                                                                
4639         return false;                                                                                    
4640     }                                                                                                    
4641                                                                                                          
4642     private boolean canRunNewAppsAnimation() {                                                           
4643         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4644         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4645     }                                                                                                    
4646                                                                                                          
4647     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4648         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4649                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4650                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4651                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4652         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4653         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4654         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4655         return bounceAnim;                                                                               
4656     }                                                                                                    
4657                                                                                                          
4658     public boolean useVerticalBarLayout() {                                                              
4659         return LauncherAppState.getInstance().getDynamicGrid().                                          
4660                 getDeviceProfile().isVerticalBarLayout();                                                
4661     }                                                                                                    
4662                                                                                                          
4663     protected Rect getSearchBarBounds() {                                                                
4664         return LauncherAppState.getInstance().getDynamicGrid().                                          
4665                 getDeviceProfile().getSearchBarBounds();                                                 
4666     }                                                                                                    
4667                                                                                                          
4668     @Override                                                                                            
4669     public void bindSearchablesChanged() {                                                               
4670         boolean searchVisible = updateGlobalSearchIcon();                                                
4671         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
4672         if (mSearchDropTargetBar != null) {                                                              
4673             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
4674         }                                                                                                
4675     }                                                                                                    
4676                                                                                                          
4677     /**                                                                                                  
4678      * Add the icons for all apps.                                                                       
4679      *                                                                                                   
4680      * Implementation of the method from LauncherModel.Callbacks.                                        
4681      */                                                                                                  
4682     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4683         if (LauncherAppState.isDisableAllApps()) {                                                       
4684             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4685                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4686                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4687                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4688                 }                                                                                        
4689                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4690             }                                                                                            
4691             if (mAppsCustomizeContent != null) {                                                         
4692                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4693                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4694             }                                                                                            
4695         } else {                                                                                         
4696             if (mAppsCustomizeContent != null) {                                                         
4697                 mAppsCustomizeContent.setApps(apps);                                                     
4698                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4699                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4700             }                                                                                            
4701         }                                                                                                
4702     }                                                                                                    
4703                                                                                                          
4704     /**                                                                                                  
4705      * A package was updated.                                                                            
4706      *                                                                                                   
4707      * Implementation of the method from LauncherModel.Callbacks.                                        
4708      */                                                                                                  
4709     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4710         Runnable r = new Runnable() {                                                                    
4711             public void run() {                                                                          
4712                 bindAppsUpdated(apps);                                                                   
4713             }                                                                                            
4714         };                                                                                               
4715         if (waitUntilResume(r)) {                                                                        
4716             return;                                                                                      
4717         }                                                                                                
4718                                                                                                          
4719         if (mWorkspace != null) {                                                                        
4720             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4721         }                                                                                                
4722                                                                                                          
4723         if (!LauncherAppState.isDisableAllApps() &&                                                      
4724                 mAppsCustomizeContent != null) {                                                         
4725             mAppsCustomizeContent.updateApps(apps);                                                      
4726         }                                                                                                
4727     }                                                                                                    
4728                                                                                                          
4729     /**                                                                                                  
4730      * Some shortcuts were updated in the background.                                                    
4731      *                                                                                                   
4732      * Implementation of the method from LauncherModel.Callbacks.                                        
4733      */                                                                                                  
4734     public void bindShortcutsUpdated(final ArrayList<ShortcutInfo> shortcuts) {                          
4735         Runnable r = new Runnable() {                                                                    
4736             public void run() {                                                                          
4737                 bindShortcutsUpdated(shortcuts);                                                         
4738             }                                                                                            
4739         };                                                                                               
4740         if (waitUntilResume(r)) {                                                                        
4741             return;                                                                                      
4742         }                                                                                                
4743                                                                                                          
4744         if (mWorkspace != null) {                                                                        
4745             mWorkspace.updateShortcuts(shortcuts);                                                       
4746         }                                                                                                
4747     }                                                                                                    
4748                                                                                                          
4749     /**                                                                                                  
4750      * Packages were restored                                                                            
4751      */                                                                                                  
4752     public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                        
4753         Runnable r = new Runnable() {                                                                    
4754             public void run() {                                                                          
4755                 bindAppsRestored(apps);                                                                  
4756             }                                                                                            
4757         };                                                                                               
4758         if (waitUntilResume(r)) {                                                                        
4759             return;                                                                                      
4760         }                                                                                                
4761                                                                                                          
4762         if (mWorkspace != null) {                                                                        
4763             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4764         }                                                                                                
4765     }                                                                                                    
4766                                                                                                          
4767     /**                                                                                                  
4768      * Update the state of a package, typically related to install state.                                
4769      *                                                                                                   
4770      * Implementation of the method from LauncherModel.Callbacks.                                        
4771      */                                                                                                  
4772     @Override                                                                                            
4773     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4774         if (mWorkspace != null) {                                                                        
4775             mWorkspace.updatePackageState(installInfo);                                                  
4776         }                                                                                                
4777     }                                                                                                    
4778                                                                                                          
4779     /**                                                                                                  
4780      * Update the label and icon of all the icons in a package                                           
4781      *                                                                                                   
4782      * Implementation of the method from LauncherModel.Callbacks.                                        
4783      */                                                                                                  
4784     @Override                                                                                            
4785     public void updatePackageBadge(String packageName) {                                                 
4786         if (mWorkspace != null) {                                                                        
4787             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4788         }                                                                                                
4789     }                                                                                                    
4790                                                                                                          
4791     /**                                                                                                  
4792      * A package was uninstalled.  We take both the super set of packageNames                            
4793      * in addition to specific applications to remove, the reason being that                             
4794      * this can be called when a package is updated as well.  In that scenario,                          
4795      * we only remove specific components from the workspace, where as                                   
4796      * package-removal should clear all items by package name.                                           
4797      *                                                                                                   
4798      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4799      * Implementation of the method from LauncherModel.Callbacks.                                        
4800      */                                                                                                  
4801     @Override                                                                                            
4802 public void bindComponentsRemoved(final ArrayList<String> packageNames,                                  
4803             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4804         Runnable r = new Runnable() {                                                                    
4805             public void run() {                                                                          
4806                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4807             }                                                                                            
4808         };                                                                                               
4809         if (waitUntilResume(r)) {                                                                        
4810             return;                                                                                      
4811         }                                                                                                
4812                                                                                                          
4813         if (reason == 0) {                                                                               
4814         if (!packageNames.isEmpty()) {                                                                   
4815             mWorkspace.removeItemsByPackageName(packageNames, user);                                     
4816         }                                                                                                
4817         if (!appInfos.isEmpty()) {                                                                       
4818             mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                     
4819         }                                                                                                
4820         } else {                                                                                         
4821             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4822         }                                                                                                
4823                                                                                                          
4824         // Notify the drag controller                                                                    
4825         mDragController.onAppsRemoved(packageNames, appInfos);                                           
4826                                                                                                          
4827         // Update AllApps                                                                                
4828         if (!LauncherAppState.isDisableAllApps() &&                                                      
4829                 mAppsCustomizeContent != null) {                                                         
4830             mAppsCustomizeContent.removeApps(appInfos);                                                  
4831         }                                                                                                
4832     }                                                                                                    
4833                                                                                                          
4834     /**                                                                                                  
4835      * A number of packages were updated.                                                                
4836      */                                                                                                  
4837     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4838     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4839             public void run() {                                                                          
4840                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4841                 mWidgetsAndShortcuts = null;                                                             
4842             }                                                                                            
4843         };                                                                                               
4844     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4845         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4846             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4847             return;                                                                                      
4848         }                                                                                                
4849                                                                                                          
4850         // Update the widgets pane                                                                       
4851         if (mAppsCustomizeContent != null) {                                                             
4852             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4853         }                                                                                                
4854     }                                                                                                    
4855                                                                                                          
4856     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4857         final Display d = getWindowManager().getDefaultDisplay();                                        
4858         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4859         switch (d.getRotation()) {                                                                       
4860         case Surface.ROTATION_0:                                                                         
4861         case Surface.ROTATION_180:                                                                       
4862             // We are currently in the same basic orientation as the natural orientation                 
4863             naturalOri = configOri;                                                                      
4864             break;                                                                                       
4865         case Surface.ROTATION_90:                                                                        
4866         case Surface.ROTATION_270:                                                                       
4867             // We are currently in the other basic orientation to the natural orientation                
4868             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4869                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4870             break;                                                                                       
4871         }                                                                                                
4872                                                                                                          
4873         int[] oriMap = {                                                                                 
4874                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4875                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4876                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4877                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4878         };                                                                                               
4879         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4880         // is landscape.                                                                                 
4881         int indexOffset = 0;                                                                             
4882         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4883             indexOffset = 1;                                                                             
4884         }                                                                                                
4885         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4886     }                                                                                                    
4887                                                                                                          
4888     public boolean isRotationEnabled() {                                                                 
4889         boolean enableRotation = sForceEnableRotation ||                                                 
4890                 getResources().getBoolean(R.bool.allow_rotation);                                        
4891         return enableRotation;                                                                           
4892     }                                                                                                    
4893     public void lockScreenOrientation() {                                                                
4894         if (isRotationEnabled()) {                                                                       
4895             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                    
4896                     .getConfiguration().orientation));                                                   
4897         }                                                                                                
4898     }                                                                                                    
4899     public void unlockScreenOrientation(boolean immediate) {                                             
4900         if (isRotationEnabled()) {                                                                       
4901             if (immediate) {                                                                             
4902                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4903             } else {                                                                                     
4904                 mHandler.postDelayed(new Runnable() {                                                    
4905                     public void run() {                                                                  
4906                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4907                     }                                                                                    
4908                 }, mRestoreScreenOrientationDelay);                                                      
4909             }                                                                                            
4910         }                                                                                                
4911     }                                                                                                    
4912                                                                                                          
4913     /**                                                                                                  
4914      * Called when the SearchBar hint should be changed.                                                 
4915      *                                                                                                   
4916      * @param hint the hint to be displayed in the search bar.                                           
4917      */                                                                                                  
4918     protected void onSearchBarHintChanged(String hint) {                                                 
4919                                                                                                          
4920     }                                                                                                    
4921                                                                                                          
4922     protected boolean isLauncherPreinstalled() {                                                         
4923         PackageManager pm = getPackageManager();                                                         
4924         try {                                                                                            
4925             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4926             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4927                 return true;                                                                             
4928             } else {                                                                                     
4929                 return false;                                                                            
4930             }                                                                                            
4931         } catch (NameNotFoundException e) {                                                              
4932             e.printStackTrace();                                                                         
4933             return false;                                                                                
4934         }                                                                                                
4935     }                                                                                                    
4936                                                                                                          
4937     /**                                                                                                  
4938      * This method indicates whether or not we should suggest default wallpaper dimensions               
4939      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4940      */                                                                                                  
4941     protected boolean overrideWallpaperDimensions() {                                                    
4942         return true;                                                                                     
4943     }                                                                                                    
4944                                                                                                          
4945     /**                                                                                                  
4946      * To be overridden by subclasses to indicate that there is an activity to launch                    
4947      * before showing the standard launcher experience.                                                  
4948      */                                                                                                  
4949     protected boolean hasFirstRunActivity() {                                                            
4950         return false;                                                                                    
4951     }                                                                                                    
4952                                                                                                          
4953     /**                                                                                                  
4954      * To be overridden by subclasses to launch any first run activity                                   
4955      */                                                                                                  
4956     protected Intent getFirstRunActivity() {                                                             
4957         return null;                                                                                     
4958     }                                                                                                    
4959                                                                                                          
4960     private boolean shouldRunFirstRunActivity() {                                                        
4961         return !ActivityManager.isRunningInTestHarness() &&                                              
4962                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4963     }                                                                                                    
4964                                                                                                          
4965     protected boolean hasRunFirstRunActivity() {                                                         
4966         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4967     }                                                                                                    
4968                                                                                                          
4969     public boolean showFirstRunActivity() {                                                              
4970         if (shouldRunFirstRunActivity() &&                                                               
4971                 hasFirstRunActivity()) {                                                                 
4972             Intent firstRunIntent = getFirstRunActivity();                                               
4973             if (firstRunIntent != null) {                                                                
4974                 startActivity(firstRunIntent);                                                           
4975                 markFirstRunActivityShown();                                                             
4976                 return true;                                                                             
4977             }                                                                                            
4978         }                                                                                                
4979         return false;                                                                                    
4980     }                                                                                                    
4981                                                                                                          
4982     private void markFirstRunActivityShown() {                                                           
4983         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4984         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4985         editor.apply();                                                                                  
4986     }                                                                                                    
4987                                                                                                          
4988     /**                                                                                                  
4989      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4990      * screen that must be displayed and dismissed.                                                      
4991      */                                                                                                  
4992     protected boolean hasDismissableIntroScreen() {                                                      
4993         return false;                                                                                    
4994     }                                                                                                    
4995                                                                                                          
4996     /**                                                                                                  
4997      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4998      */                                                                                                  
4999     protected View getIntroScreen() {                                                                    
5000         return null;                                                                                     
5001     }                                                                                                    
5002                                                                                                          
5003     /**                                                                                                  
5004      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
5005      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
5006      */                                                                                                  
5007     private boolean shouldShowIntroScreen() {                                                            
5008         return hasDismissableIntroScreen() &&                                                            
5009                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
5010     }                                                                                                    
5011                                                                                                          
5012     protected void showIntroScreen() {                                                                   
5013         View introScreen = getIntroScreen();                                                             
5014         changeWallpaperVisiblity(false);                                                                 
5015         if (introScreen != null) {                                                                       
5016             mDragLayer.showOverlayView(introScreen);                                                     
5017         }                                                                                                
5018     }                                                                                                    
5019                                                                                                          
5020     public void dismissIntroScreen() {                                                                   
5021         markIntroScreenDismissed();                                                                      
5022         if (showFirstRunActivity()) {                                                                    
5023             // We delay hiding the intro view until the first run activity is showing. This              
5024             // avoids a blip.                                                                            
5025             mWorkspace.postDelayed(new Runnable() {                                                      
5026                 @Override                                                                                
5027                 public void run() {                                                                      
5028                     mDragLayer.dismissOverlayView();                                                     
5029                     showFirstRunClings();                                                                
5030                 }                                                                                        
5031             }, ACTIVITY_START_DELAY);                                                                    
5032         } else {                                                                                         
5033             mDragLayer.dismissOverlayView();                                                             
5034             showFirstRunClings();                                                                        
5035         }                                                                                                
5036         changeWallpaperVisiblity(true);                                                                  
5037     }                                                                                                    
5038                                                                                                          
5039     private void markIntroScreenDismissed() {                                                            
5040         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5041         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
5042         editor.apply();                                                                                  
5043     }                                                                                                    
5044                                                                                                          
5045     private void showFirstRunClings() {                                                                  
5046         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
5047         // on the device, then we always show the first run cling experience (or if there is no          
5048         // launcher2). Otherwise, we prompt the user upon started for migration                          
5049         LauncherClings launcherClings = new LauncherClings(this);                                        
5050         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
5051             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
5052                 launcherClings.showMigrationCling();                                                     
5053             } else {                                                                                     
5054                 launcherClings.showLongPressCling(true);                                                 
5055             }                                                                                            
5056         }                                                                                                
5057     }                                                                                                    
5058                                                                                                          
5059     void showWorkspaceSearchAndHotseat() {                                                               
5060         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
5061         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
5062         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
5063         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
5064     }                                                                                                    
5065                                                                                                          
5066     void hideWorkspaceSearchAndHotseat() {                                                               
5067         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
5068         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
5069         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
5070         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
5071     }                                                                                                    
5072                                                                                                          
5073     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
5074         // Called from search suggestion, not supported in other profiles.                               
5075         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
5076         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
5077         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
5078                 myUser);                                                                                 
5079         if (activityInfo == null) {                                                                      
5080             return null;                                                                                 
5081         }                                                                                                
5082         return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                
5083     }                                                                                                    
5084                                                                                                          
5085     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5086             Bitmap icon) {                                                                               
5087         // Called from search suggestion, not supported in other profiles.                               
5088         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
5089                 UserHandleCompat.myUserHandle());                                                        
5090     }                                                                                                    
5091                                                                                                          
5092     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5093             Bitmap icon, UserHandleCompat user) {                                                        
5094         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
5095         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
5096         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
5097     }                                                                                                    
5098                                                                                                          
5099     protected void moveWorkspaceToDefaultScreen() {                                                      
5100         mWorkspace.moveToDefaultScreen(false);                                                           
5101     }                                                                                                    
5102                                                                                                          
5103     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
5104         dragView.setTag(dragInfo);                                                                       
5105         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
5106         mWorkspace.beginExternalDragShared(dragView, source);                                            
5107     }                                                                                                    
5108                                                                                                          
5109     @Override                                                                                            
5110     public void onPageSwitch(View newPage, int newPageIndex) {                                           
5111     }                                                                                                    
5112                                                                                                          
5113     /**                                                                                                  
5114      * Prints out out state for debugging.                                                               
5115      */                                                                                                  
5116     public void dumpState() {                                                                            
5117         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
5118         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
5119         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
5120         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
5121         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
5122         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
5123         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
5124         mModel.dumpState();                                                                              
5125                                                                                                          
5126         if (mAppsCustomizeContent != null) {                                                             
5127             mAppsCustomizeContent.dumpState();                                                           
5128         }                                                                                                
5129         Log.d(TAG, "END launcher3 dump state");                                                          
5130     }                                                                                                    
5131                                                                                                          
5132     @Override                                                                                            
5133     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
5134         super.dump(prefix, fd, writer, args);                                                            
5135         synchronized (sDumpLogs) {                                                                       
5136             writer.println(" ");                                                                         
5137             writer.println("Debug logs: ");                                                              
5138             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
5139                 writer.println("  " + sDumpLogs.get(i));                                                 
5140             }                                                                                            
5141         }                                                                                                
5142     }                                                                                                    
5143                                                                                                          
5144     public static void dumpDebugLogsToConsole() {                                                        
5145         if (DEBUG_DUMP_LOG) {                                                                            
5146             synchronized (sDumpLogs) {                                                                   
5147                 Log.d(TAG, "");                                                                          
5148                 Log.d(TAG, "*********************");                                                     
5149                 Log.d(TAG, "Launcher debug logs: ");                                                     
5150                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
5151                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
5152                 }                                                                                        
5153                 Log.d(TAG, "*********************");                                                     
5154                 Log.d(TAG, "");                                                                          
5155             }                                                                                            
5156         }                                                                                                
5157     }                                                                                                    
5158                                                                                                          
5159     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
5160         addDumpLog(tag, log, null, debugLog);                                                            
5161     }                                                                                                    
5162                                                                                                          
5163     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
5164         if (debugLog) {                                                                                  
5165             if (e != null) {                                                                             
5166                 Log.d(tag, log, e);                                                                      
5167             } else {                                                                                     
5168                 Log.d(tag, log);                                                                         
5169             }                                                                                            
5170         }                                                                                                
5171         if (DEBUG_DUMP_LOG) {                                                                            
5172             sDateStamp.setTime(System.currentTimeMillis());                                              
5173             synchronized (sDumpLogs) {                                                                   
5174                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
5175                     + (e == null ? "" : (", Exception: " + e)));                                         
5176             }                                                                                            
5177         }                                                                                                
5178     }                                                                                                    
5179                                                                                                          
5180     public void dumpLogsToLocalData() {                                                                  
5181         if (DEBUG_DUMP_LOG) {                                                                            
5182             new AsyncTask<Void, Void, Void>() {                                                          
5183                 public Void doInBackground(Void ... args) {                                              
5184                     boolean success = false;                                                             
5185                     sDateStamp.setTime(sRunStart);                                                       
5186                     String FILENAME = sDateStamp.getMonth() + "-"                                        
5187                             + sDateStamp.getDay() + "_"                                                  
5188                             + sDateStamp.getHours() + "-"                                                
5189                             + sDateStamp.getMinutes() + "_"                                              
5190                             + sDateStamp.getSeconds() + ".txt";                                          
5191                                                                                                          
5192                     FileOutputStream fos = null;                                                         
5193                     File outFile = null;                                                                 
5194                     try {                                                                                
5195                         outFile = new File(getFilesDir(), FILENAME);                                     
5196                         outFile.createNewFile();                                                         
5197                         fos = new FileOutputStream(outFile);                                             
5198                     } catch (Exception e) {                                                              
5199                         e.printStackTrace();                                                             
5200                     }                                                                                    
5201                     if (fos != null) {                                                                   
5202                         PrintWriter writer = new PrintWriter(fos);                                       
5203                                                                                                          
5204                         writer.println(" ");                                                             
5205                         writer.println("Debug logs: ");                                                  
5206                         synchronized (sDumpLogs) {                                                       
5207                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
5208                                 writer.println("  " + sDumpLogs.get(i));                                 
5209                             }                                                                            
5210                         }                                                                                
5211                         writer.close();                                                                  
5212                     }                                                                                    
5213                     try {                                                                                
5214                         if (fos != null) {                                                               
5215                             fos.close();                                                                 
5216                             success = true;                                                              
5217                         }                                                                                
5218                     } catch (IOException e) {                                                            
5219                         e.printStackTrace();                                                             
5220                     }                                                                                    
5221                     return null;                                                                         
5222                 }                                                                                        
5223             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
5224         }                                                                                                
5225     }                                                                                                    
5226 }                                                                                                        
5227                                                                                                          
5228 interface LauncherTransitionable {                                                                       
5229     View getContent();                                                                                   
5230     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
5231     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
5232     void onLauncherTransitionStep(Launcher l, float t);                                                  
5233     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
5234 }                                                                                                        
5235                                                                                                          
5236 interface DebugIntents {                                                                                 
5237     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
5238     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
5239 }                                                                                                        




















































































   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16 package com.android.launcher3;                                                                           
  17                                                                                                          
  18 import android.animation.Animator;                                                                       
  19 import android.animation.AnimatorListenerAdapter;                                                        
  20 import android.animation.AnimatorSet;                                                                    
  21 import android.animation.ObjectAnimator;                                                                 
  22 import android.animation.PropertyValuesHolder;                                                           
  23 import android.animation.TimeInterpolator;                                                               
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.SharedPreferences;                                                                
  44 import android.content.pm.ActivityInfo;                                                                  
  45 import android.content.pm.ApplicationInfo;                                                               
  46 import android.content.pm.PackageManager.NameNotFoundException;                                          
  47 import android.content.pm.PackageManager;                                                                
  48 import android.content.res.Configuration;                                                                
  49 import android.content.res.Resources;                                                                    
  50 import android.database.ContentObserver;                                                                 
  51 import android.graphics.Bitmap;                                                                          
  52 import android.graphics.Canvas;                                                                          
  53 import android.graphics.Color;                                                                           
  54 import android.graphics.Point;                                                                           
  55 import android.graphics.PorterDuff;                                                                      
  56 import android.graphics.Rect;                                                                            
  57 import android.graphics.drawable.Drawable;                                                               
  58 import android.net.Uri;                                                                                  
  59 import android.os.AsyncTask;                                                                             
  60 import android.os.Build;                                                                                 
  61 import android.os.Bundle;                                                                                
  62 import android.os.Environment;                                                                           
  63 import android.os.Handler;                                                                               
  64 import android.os.Message;                                                                               
  65 import android.os.StrictMode;                                                                            
  66 import android.os.SystemClock;                                                                           
  67 import android.speech.RecognizerIntent;                                                                  
  68 import android.text.Selection;                                                                           
  69 import android.text.SpannableStringBuilder;                                                              
  70 import android.text.TextUtils;                                                                           
  71 import android.text.method.TextKeyListener;                                                              
  72 import android.util.DisplayMetrics;                                                                      
  73 import android.util.Log;                                                                                 
  74 import android.view.Display;                                                                             
  75 import android.view.Gravity;                                                                             
  76 import android.view.HapticFeedbackConstants;                                                             
  77 import android.view.KeyEvent;                                                                            
  78 import android.view.LayoutInflater;                                                                      
  79 import android.view.Menu;                                                                                
  80 import android.view.MotionEvent;                                                                         
  81 import android.view.Surface;                                                                             
  82 import android.view.View.OnClickListener;                                                                
  83 import android.view.View.OnLongClickListener;                                                            
  84 import android.view.View;                                                                                
  85 import android.view.ViewAnimationUtils;                                                                  
  86 import android.view.ViewGroup;                                                                           
  87 import android.view.ViewTreeObserver;                                                                    
  88 import android.view.Window;                                                                              
  89 import android.view.WindowManager;                                                                       
  90 import android.view.accessibility.AccessibilityEvent;                                                    
  91 import android.view.animation.AccelerateInterpolator;                                                    
  92 import android.view.animation.DecelerateInterpolator;                                                    
  93 import android.view.inputmethod.InputMethodManager;                                                      
  94 import android.widget.Advanceable;                                                                       
  95 import android.widget.FrameLayout;                                                                       
  96 import android.widget.ImageView;                                                                         
  97 import android.widget.TextView;                                                                          
  98 import android.widget.Toast;                                                                             
  99 import com.android.launcher3.DropTarget.DragObject;                                                      
 100 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 101 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 102 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 103 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 104 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 105 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 106 import com.android.launcher3.compat.UserHandleCompat;                                                    
 107 import com.android.launcher3.compat.UserManagerCompat;                                                   
 108 import java.io.DataInputStream;                                                                          
 109 import java.io.DataOutputStream;                                                                         
 110 import java.io.File;                                                                                     
 111 import java.io.FileDescriptor;                                                                           
 112 import java.io.FileNotFoundException;                                                                    
 113 import java.io.FileOutputStream;                                                                         
 114 import java.io.IOException;                                                                              
 115 import java.io.PrintWriter;                                                                              
 116 import java.lang.reflect.Field;                                                                          
 117 import java.lang.reflect.InvocationTargetException;                                                      
 118 import java.lang.reflect.Method;                                                                         
 119 import java.text.DateFormat;                                                                             
 120 import java.util.ArrayList;                                                                              
 121 import java.util.Collection;                                                                             
 122 import java.util.Date;                                                                                   
 123 import java.util.HashMap;                                                                                
 124 import java.util.List;                                                                                   
 125 import java.util.concurrent.atomic.AtomicInteger;                                                        
 126                                                                                                          
 127                                                                                                          
 128 interface DebugIntents {                                                                                 
 129     public static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";         
 130                                                                                                          
 131     public static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";       
 132 }                                                                                                        
 133                                                                                                          
 134 /**                                                                                                      
 135  * Default launcher application.                                                                         
 136  */                                                                                                      
 137 public class Launcher extends Activity implements View.OnClickListener , OnLongClickListener , LauncherMo🔵
 138     static final String TAG = "Launcher";                                                                
 139                                                                                                          
 140     static final boolean LOGD = false;                                                                   
 141                                                                                                          
 142     static final boolean PROFILE_STARTUP = false;                                                        
 143                                                                                                          
 144     static final boolean DEBUG_WIDGETS = false;                                                          
 145                                                                                                          
 146     static final boolean DEBUG_STRICT_MODE = false;                                                      
 147                                                                                                          
 148     static final boolean DEBUG_RESUME_TIME = false;                                                      
 149                                                                                                          
 150     static final boolean DEBUG_DUMP_LOG = false;                                                         
 151                                                                                                          
 152     // allow DebugIntents to run                                                                         
 153     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 154                                                                                                          
 155     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 156                                                                                                          
 157     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 158                                                                                                          
 159     private static final int REQUEST_PICK_SHORTCUT = 7;                                                  
 160                                                                                                          
 161     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 162                                                                                                          
 163     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 164                                                                                                          
 165     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 166                                                                                                          
 167     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 168                                                                                                          
 169     /**                                                                                                  
 170      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 171      * request codes used internally.                                                                    
 172      */                                                                                                  
 173     protected static final int REQUEST_LAST = 100;                                                       
 174                                                                                                          
 175     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 176                                                                                                          
 177     static final int SCREEN_COUNT = 5;                                                                   
 178                                                                                                          
 179     static final int DEFAULT_SCREEN = 2;                                                                 
 180                                                                                                          
 181     // To turn on these properties, type                                                                 
 182     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 183     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                        
 184                                                                                                          
 185     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 186                                                                                                          
 187     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                
 188                                                                                                          
 189     // The Intent extra that defines whether to ignore the launch animation                              
 190     // The Intent extra that defines whether to ignore the launch animation                              
 191     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 192             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 193                                                                                                          
 194     // Type: int                                                                                         
 195     // Type: int                                                                                         
 196     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 197                                                                                                          
 198     // Type: int                                                                                         
 199     // Type: int                                                                                         
 200     private static final String RUNTIME_STATE = "launcher.state";                                        
 201                                                                                                          
 202     // Type: int                                                                                         
 203     // Type: int                                                                                         
 204     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 205                                                                                                          
 206     // Type: int                                                                                         
 207     // Type: int                                                                                         
 208     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 209                                                                                                          
 210     // Type: int                                                                                         
 211     // Type: int                                                                                         
 212     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 213                                                                                                          
 214     // Type: int                                                                                         
 215     // Type: int                                                                                         
 216     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 217                                                                                                          
 218     // Type: boolean                                                                                     
 219     // Type: boolean                                                                                     
 220     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 221                                                                                                          
 222     // Type: long                                                                                        
 223     // Type: long                                                                                        
 224     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 225                                                                                                          
 226     // Type: int                                                                                         
 227     // Type: int                                                                                         
 228     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 229                                                                                                          
 230     // Type: int                                                                                         
 231     // Type: int                                                                                         
 232     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 233                                                                                                          
 234     // Type: parcelable                                                                                  
 235     // Type: parcelable                                                                                  
 236     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 237                                                                                                          
 238     // Type: parcelable                                                                                  
 239     // Type: parcelable                                                                                  
 240     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 241                                                                                                          
 242     // Type: int[]                                                                                       
 243     // Type: int[]                                                                                       
 244     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 245                                                                                                          
 246     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 247                                                                                                          
 248     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 249                                                                                                          
 250     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 251                                                                                                          
 252     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 253             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 254                                                                                                          
 255     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";        
 256                                                                                                          
 257     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                      
 258             "com.android.launcher.toolbar_search_icon";                                                  
 259                                                                                                          
 260     private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                
 261             "com.android.launcher.toolbar_voice_search_icon";                                            
 262                                                                                                          
 263     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 264                                                                                                          
 265     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 266                                                                                                          
 267     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 268                                                                                                          
 269     /**                                                                                                  
 270      * The different states that Launcher can be in.                                                     
 271      */                                                                                                  
 272     private enum State {                                                                                 
 273                                                                                                          
 274         NONE,                                                                                            
 275         WORKSPACE,                                                                                       
 276         APPS_CUSTOMIZE,                                                                                  
 277         APPS_CUSTOMIZE_SPRING_LOADED;}                                                                   
 278                                                                                                          
 279     private State mState = State.WORKSPACE;                                                              
 280                                                                                                          
 281     private AnimatorSet mStateAnimation;                                                                 
 282                                                                                                          
 283     private boolean mIsSafeModeEnabled;                                                                  
 284                                                                                                          
 285     static final int APPWIDGET_HOST_ID = 1024;                                                           
 286                                                                                                          
 287     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 288                                                                                                          
 289     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 290                                                                                                          
 291     private static final int ACTIVITY_START_DELAY = 1000;                                                
 292                                                                                                          
 293     private static final Object sLock = new Object();                                                    
 294                                                                                                          
 295     private static int sScreen = DEFAULT_SCREEN;                                                         
 296                                                                                                          
 297     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 298                                                                                                          
 299     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 300                                                                                                          
 301     // How long to wait before the new-shortcut animation automatically pans the workspace               
 302     // How long to wait before the new-shortcut animation automatically pans the workspace               
 303     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 304                                                                                                          
 305     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 306                                                                                                          
 307     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 308                                                                                                          
 309     private static final int SINGLE_FRAME_DELAY = 16;                                                    
 310                                                                                                          
 311     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 312             = new CloseSystemDialogsIntentReceiver();                                                    
 313                                                                                                          
 314     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 315                                                                                                          
 316     private LayoutInflater mInflater;                                                                    
 317                                                                                                          
 318     private Workspace mWorkspace;                                                                        
 319                                                                                                          
 320     private View mLauncherView;                                                                          
 321                                                                                                          
 322     private View mPageIndicators;                                                                        
 323                                                                                                          
 324     private DragLayer mDragLayer;                                                                        
 325                                                                                                          
 326     private DragController mDragController;                                                              
 327                                                                                                          
 328     private View mWeightWatcher;                                                                         
 329                                                                                                          
 330     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 331                                                                                                          
 332     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 333                                                                                                          
 334     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 335                                                                                                          
 336     private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                 
 337                                                                                                          
 338     private int mPendingAddWidgetId = -1;                                                                
 339                                                                                                          
 340     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 341                                                                                                          
 342     private FolderInfo mFolderInfo;                                                                      
 343                                                                                                          
 344     private Hotseat mHotseat;                                                                            
 345                                                                                                          
 346     private ViewGroup mOverviewPanel;                                                                    
 347                                                                                                          
 348     private View mAllAppsButton;                                                                         
 349                                                                                                          
 350     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 351                                                                                                          
 352     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 353                                                                                                          
 354     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 355                                                                                                          
 356     private boolean mAutoAdvanceRunning = false;                                                         
 357                                                                                                          
 358     private View mQsb;                                                                                   
 359                                                                                                          
 360     private Bundle mSavedState;                                                                          
 361                                                                                                          
 362     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 363     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 364     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 365     private State mOnResumeState = State.NONE;                                                           
 366                                                                                                          
 367     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 368                                                                                                          
 369     private boolean mWorkspaceLoading = true;                                                            
 370                                                                                                          
 371     private boolean mPaused = true;                                                                      
 372                                                                                                          
 373     private boolean mRestoring;                                                                          
 374                                                                                                          
 375     private boolean mWaitingForResult;                                                                   
 376                                                                                                          
 377     private boolean mOnResumeNeedsLoad;                                                                  
 378                                                                                                          
 379     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 380                                                                                                          
 381     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 382                                                                                                          
 383     private Bundle mSavedInstanceState;                                                                  
 384                                                                                                          
 385     private LauncherModel mModel;                                                                        
 386                                                                                                          
 387     private IconCache mIconCache;                                                                        
 388                                                                                                          
 389     private boolean mUserPresent = true;                                                                 
 390                                                                                                          
 391     private boolean mVisible = false;                                                                    
 392                                                                                                          
 393     private boolean mHasFocus = false;                                                                   
 394                                                                                                          
 395     private boolean mAttached = false;                                                                   
 396                                                                                                          
 397     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 398                                                                                                          
 399     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 400                                                                                                          
 401     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 402                                                                                                          
 403     // Related to the auto-advancing of widgets                                                          
 404     // Related to the auto-advancing of widgets                                                          
 405     private final int ADVANCE_MSG = 1;                                                                   
 406                                                                                                          
 407     private final int mAdvanceInterval = 20000;                                                          
 408                                                                                                          
 409     private final int mAdvanceStagger = 250;                                                             
 410                                                                                                          
 411     private long mAutoAdvanceSentTime;                                                                   
 412                                                                                                          
 413     private long mAutoAdvanceTimeLeft = -1;                                                              
 414                                                                                                          
 415     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance = new HashMap<View, AppWidgetProviderI🔵
 416                                                                                                          
 417     // Determines how long to wait after a rotation before restoring the screen orientation to           
 418     // match the sensor state.                                                                           
 419     // Determines how long to wait after a rotation before restoring the screen orientation to           
 420     // match the sensor state.                                                                           
 421     private final int mRestoreScreenOrientationDelay = 500;                                              
 422                                                                                                          
 423     // External icons saved in case of resource changes, orientation, etc.                               
 424     private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];           
 425                                                                                                          
 426     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];            
 427                                                                                                          
 428     private Drawable mWorkspaceBackgroundDrawable;                                                       
 429                                                                                                          
 430     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 431                                                                                                          
 432     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 433                                                                                                          
 434     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 435                                                                                                          
 436     static Date sDateStamp = new Date();                                                                 
 437                                                                                                          
 438     static DateFormat sDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);  
 439                                                                                                          
 440     static long sRunStart = System.currentTimeMillis();                                                  
 441                                                                                                          
 442     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 443                                                                                                          
 444     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 445     // it from the context.                                                                              
 446     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 447     // it from the context.                                                                              
 448     private SharedPreferences mSharedPrefs;                                                              
 449                                                                                                          
 450     private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                   
 451                                                                                                          
 452     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 453     // when we scroll to that page on resume.                                                            
 454     private ImageView mFolderIconImageView;                                                              
 455                                                                                                          
 456     private Bitmap mFolderIconBitmap;                                                                    
 457                                                                                                          
 458     private Canvas mFolderIconCanvas;                                                                    
 459                                                                                                          
 460     private Rect mRectForFolderAnimation = new Rect();                                                   
 461                                                                                                          
 462     private BubbleTextView mWaitingForResume;                                                            
 463                                                                                                          
 464     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 465         public void run() {                                                                              
 466             if (mWorkspace != null) {                                                                    
 467                 mWorkspace.buildPageHardwareLayers();                                                    
 468             }                                                                                            
 469         }                                                                                                
 470     };                                                                                                   
 471                                                                                                          
 472     private static PendingAddArguments sPendingAddItem;                                                  
 473                                                                                                          
 474     public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);      
 475                                                                                                          
 476     private static class PendingAddArguments {                                                           
 477         int requestCode;                                                                                 
 478                                                                                                          
 479         Intent intent;                                                                                   
 480                                                                                                          
 481         long container;                                                                                  
 482                                                                                                          
 483         long screenId;                                                                                   
 484                                                                                                          
 485         int cellX;                                                                                       
 486                                                                                                          
 487         int cellY;                                                                                       
 488                                                                                                          
 489         int appWidgetId;                                                                                 
 490     }                                                                                                    
 491                                                                                                          
 492     private Stats mStats;                                                                                
 493                                                                                                          
 494     FocusIndicatorView mFocusHandler;                                                                    
 495                                                                                                          
 496     static boolean isPropertyEnabled(String propertyName) {                                              
 497         return Log.isLoggable(propertyName, Log.VERBOSE);                                                
 498     }                                                                                                    
 499                                                                                                          
 500     @Override                                                                                            
 501     protected void onCreate(Bundle savedInstanceState) {                                                 
 502         if (DEBUG_STRICT_MODE) {                                                                         
 503             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 504                     .detectDiskReads()                                                                   
 505                     .detectDiskWrites()                                                                  
 506                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 507                     .penaltyLog()                                                                        
 508                     .build());                                                                           
 509             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 510                     .detectLeakedSqlLiteObjects()                                                        
 511                     .detectLeakedClosableObjects()                                                       
 512                     .penaltyLog()                                                                        
 513                     .penaltyDeath()                                                                      
 514                     .build());                                                                           
 515         }                                                                                                
 516                                                                                                          
 517         super.onCreate(savedInstanceState);                                                              
 518                                                                                                          
 519         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 520         LauncherAppState app = LauncherAppState.getInstance();                                           
 521         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 522         // Determine the dynamic grid properties                                                         
 523         Point smallestSize = new Point();                                                                
 524         Point largestSize = new Point();                                                                 
 525         Point realSize = new Point();                                                                    
 526         Display display = getWindowManager().getDefaultDisplay();                                        
 527         display.getCurrentSizeRange(smallestSize, largestSize);                                          
 528         display.getRealSize(realSize);                                                                   
 529         DisplayMetrics dm = new DisplayMetrics();                                                        
 530         display.getMetrics(dm);                                                                          
 531                                                                                                          
 532         // Lazy-initialize the dynamic grid                                                              
 533         DeviceProfile grid = app.initDynamicGrid(this,                                                   
 534                 Math.min(smallestSize.x, smallestSize.y),                                                
 535                 Math.min(largestSize.x, largestSize.y),                                                  
 536                 realSize.x, realSize.y,                                                                  
 537                 dm.widthPixels, dm.heightPixels);                                                        
 538                                                                                                          
 539         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 540         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 541                 Context.MODE_PRIVATE);                                                                   
 542         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 543         mModel = app.setLauncher(this);                                                                  
 544         mIconCache = app.getIconCache();                                                                 
 545         mIconCache.flushInvalidIcons(grid);                                                              
 546         mDragController = new DragController(this);                                                      
 547         mInflater = getLayoutInflater();                                                                 
 548                                                                                                          
 549         mStats = new Stats(this);                                                                        
 550                                                                                                          
 551         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 552                                                                                                          
 553         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 554         mAppWidgetHost.startListening();                                                                 
 555                                                                                                          
 556         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 557         // this also ensures that any synchronous binding below doesn't re-trigger another               
 558         // LauncherModel load.                                                                           
 559         mPaused = false;                                                                                 
 560                                                                                                          
 561         if (PROFILE_STARTUP) {                                                                           
 562             android.os.Debug.startMethodTracing(                                                         
 563                     Environment.getExternalStorageDirectory() + "/launcher");                            
 564         }                                                                                                
 565                                                                                                          
 566         checkForLocaleChange();                                                                          
 567         setContentView(R.layout.launcher);                                                               
 568                                                                                                          
 569         setupViews();                                                                                    
 570         grid.layout(this);                                                                               
 571                                                                                                          
 572         registerContentObservers();                                                                      
 573                                                                                                          
 574         lockAllApps();                                                                                   
 575                                                                                                          
 576         mSavedState = savedInstanceState;                                                                
 577         restoreState(mSavedState);                                                                       
 578                                                                                                          
 579         if (PROFILE_STARTUP) {                                                                           
 580             android.os.Debug.stopMethodTracing();                                                        
 581         }                                                                                                
 582                                                                                                          
 583         if (!mRestoring) {                                                                               
 584             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 585                 // If the user leaves launcher, then we should just load items asynchronously when       
 586                 // they return.                                                                          
 587                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 588             } else {                                                                                     
 589                 // We only load the page synchronously if the user rotates (or triggers a                
 590                 // configuration change) while launcher is in the foreground                             
 591                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 592             }                                                                                            
 593         }                                                                                                
 594                                                                                                          
 595         // For handling default keys                                                                     
 596         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 597         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 598                                                                                                          
 599         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 600         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 601                                                                                                          
 602         updateGlobalIcons();                                                                             
 603                                                                                                          
 604         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 605         unlockScreenOrientation(true);                                                                   
 606                                                                                                          
 607         if (shouldShowIntroScreen()) {                                                                   
 608             showIntroScreen();                                                                           
 609         } else {                                                                                         
 610             showFirstRunActivity();                                                                      
 611             showFirstRunClings();                                                                        
 612         }                                                                                                
 613     }                                                                                                    
 614                                                                                                          
 615     @Override                                                                                            
 616     public void onLauncherProviderChange() { }                                                           
 617                                                                                                          
 618     /** To be overriden by subclasses to hint to Launcher that we have custom content */                 
 619     protected boolean hasCustomContentToLeft() {                                                         
 620         return false;                                                                                    
 621     }                                                                                                    
 622                                                                                                          
 623     /**                                                                                                  
 624      * To be overridden by subclasses to populate the custom content container and call                  
 625      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 626      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 627      */                                                                                                  
 628     protected void populateCustomContentContainer() {                                                    
 629     }                                                                                                    
 630                                                                                                          
 631     /**                                                                                                  
 632      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 633      * ensure the custom content page is added or removed if necessary.                                  
 634      */                                                                                                  
 635     protected void invalidateHasCustomContentToLeft() {                                                  
 636         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 637             // Not bound yet, wait for bindScreens to be called.                                         
 638             return;                                                                                      
 639         }                                                                                                
 640                                                                                                          
 641         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 642             // Create the custom content page and call the subclass to populate it.                      
 643             mWorkspace.createCustomContentContainer();                                                   
 644             populateCustomContentContainer();                                                            
 645         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 646             mWorkspace.removeCustomContentPage();                                                        
 647         }                                                                                                
 648     }                                                                                                    
 649                                                                                                          
 650     private void updateGlobalIcons() {                                                                   
 651         boolean searchVisible = false;                                                                   
 652         boolean voiceVisible = false;                                                                    
 653         // If we have a saved version of these external icons, we load them up immediately               
 654         int coi = getCurrentOrientationIndexForGlobalIcons();                                            
 655         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                           
 656             searchVisible = updateGlobalSearchIcon();                                                    
 657             voiceVisible = updateVoiceSearchIcon(searchVisible);                                         
 658         }                                                                                                
 659         if (sGlobalSearchIcon[coi] != null) {                                                            
 660              updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                             
 661              searchVisible = true;                                                                       
 662         }                                                                                                
 663         if (sVoiceSearchIcon[coi] != null) {                                                             
 664             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                
 665             voiceVisible = true;                                                                         
 666         }                                                                                                
 667         if (mSearchDropTargetBar != null) {                                                              
 668             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
 669         }                                                                                                
 670     }                                                                                                    
 671                                                                                                          
 672     private void checkForLocaleChange() {                                                                
 673         if (sLocaleConfiguration == null) {                                                              
 674             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 675                 @Override                                                                                
 676                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 677                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 678                     readConfiguration(Launcher.this, localeConfiguration);                               
 679                     return localeConfiguration;                                                          
 680                 }                                                                                        
 681                                                                                                          
 682                 @Override                                                                                
 683                 protected void onPostExecute(LocaleConfiguration result) {                               
 684                     sLocaleConfiguration = result;                                                       
 685                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 686                 }                                                                                        
 687             }.execute();                                                                                 
 688             return;                                                                                      
 689         }                                                                                                
 690                                                                                                          
 691         final Configuration configuration = getResources().getConfiguration();                           
 692                                                                                                          
 693         final String previousLocale = sLocaleConfiguration.locale;                                       
 694         final String locale = configuration.locale.toString();                                           
 695                                                                                                          
 696         final int previousMcc = sLocaleConfiguration.mcc;                                                
 697         final int mcc = configuration.mcc;                                                               
 698                                                                                                          
 699         final int previousMnc = sLocaleConfiguration.mnc;                                                
 700         final int mnc = configuration.mnc;                                                               
 701                                                                                                          
 702         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 703                                                                                                          
 704         if (localeChanged) {                                                                             
 705             sLocaleConfiguration.locale = locale;                                                        
 706             sLocaleConfiguration.mcc = mcc;                                                              
 707             sLocaleConfiguration.mnc = mnc;                                                              
 708                                                                                                          
 709             mIconCache.flush();                                                                          
 710                                                                                                          
 711             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 712             new AsyncTask<Void, Void, Void>() {                                                          
 713                 public Void doInBackground(Void ... args) {                                              
 714                     writeConfiguration(Launcher.this, localeConfiguration);                              
 715                     return null;                                                                         
 716                 }                                                                                        
 717             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 718         }                                                                                                
 719     }                                                                                                    
 720                                                                                                          
 721     private static class LocaleConfiguration {                                                           
 722         public String locale;                                                                            
 723                                                                                                          
 724         public int mcc = -1;                                                                             
 725                                                                                                          
 726         public int mnc = -1;                                                                             
 727     }                                                                                                    
 728                                                                                                          
 729     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 730         DataInputStream in = null;                                                                       
 731         try {                                                                                            
 732             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFS));               
 733             configuration.locale = in.readUTF();                                                         
 734             configuration.mcc = in.readInt();                                                            
 735             configuration.mnc = in.readInt();                                                            
 736         } catch (FileNotFoundException e) {                                                              
 737             // Ignore                                                                                    
 738         } catch (IOException e) {                                                                        
 739             // Ignore                                                                                    
 740         } finally {                                                                                      
 741             if (in != null) {                                                                            
 742                 try {                                                                                    
 743                     in.close();                                                                          
 744                 } catch (IOException e) {                                                                
 745                     // Ignore                                                                            
 746                 }                                                                                        
 747             }                                                                                            
 748         }                                                                                                
 749     }                                                                                                    
 750                                                                                                          
 751     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 752         DataOutputStream out = null;                                                                     
 753         try {                                                                                            
 754             out = new DataOutputStream(context.openFileOutput(LauncherFiles.LAUNCHER_PREFS, MODE_PRIVATE)🔵
 755             out.writeUTF(configuration.locale);                                                          
 756             out.writeInt(configuration.mcc);                                                             
 757             out.writeInt(configuration.mnc);                                                             
 758             out.flush();                                                                                 
 759         } catch (FileNotFoundException e) {                                                              
 760             // Ignore                                                                                    
 761         } catch (IOException e) {                                                                        
 762             //noinspection ResultOfMethodCallIgnored                                                     
 763             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFS).delete();                            
 764         } finally {                                                                                      
 765             if (out != null) {                                                                           
 766                 try {                                                                                    
 767                     out.close();                                                                         
 768                 } catch (IOException e) {                                                                
 769                     // Ignore                                                                            
 770                 }                                                                                        
 771             }                                                                                            
 772         }                                                                                                
 773     }                                                                                                    
 774                                                                                                          
 775     public Stats getStats() {                                                                            
 776         return mStats;                                                                                   
 777     }                                                                                                    
 778                                                                                                          
 779     public LayoutInflater getInflater() {                                                                
 780         return mInflater;                                                                                
 781     }                                                                                                    
 782                                                                                                          
 783     boolean isDraggingEnabled() {                                                                        
 784         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 785         // that is subsequently removed from the workspace in startBinding().                            
 786         return !mModel.isLoadingWorkspace();                                                             
 787     }                                                                                                    
 788                                                                                                          
 789     static int getScreen() {                                                                             
 790         synchronized (sLock) {                                                                           
 791             return sScreen;                                                                              
 792         }                                                                                                
 793     }                                                                                                    
 794                                                                                                          
 795     static void setScreen(int screen) {                                                                  
 796         synchronized (sLock) {                                                                           
 797             sScreen = screen;                                                                            
 798         }                                                                                                
 799     }                                                                                                    
 800                                                                                                          
 801     public static int generateViewId() {                                                                 
 802         if (Build.VERSION.SDK_INT >= 17) {                                                               
 803             return View.generateViewId();                                                                
 804         } else {                                                                                         
 805             // View.generateViewId() is not available. The following fallback logic is a copy            
 806             // of its implementation.                                                                    
 807             for (;;) {                                                                                   
 808                 final int result = sNextGeneratedId.get();                                               
 809                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 810                 int newValue = result + 1;                                                               
 811                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 812                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 813                     return result;                                                                       
 814                 }                                                                                        
 815             }                                                                                            
 816         }                                                                                                
 817     }                                                                                                    
 818                                                                                                          
 819     public int getViewIdForItem(ItemInfo info) {                                                         
 820         // This cast is safe given the > 2B range for int.                                               
 821         int itemId = (int) info.id;                                                                      
 822         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 823             return mItemIdToViewId.get(itemId);                                                          
 824         }                                                                                                
 825         int viewId = generateViewId();                                                                   
 826         mItemIdToViewId.put(itemId, viewId);                                                             
 827         return viewId;                                                                                   
 828     }                                                                                                    
 829                                                                                                          
 830     /**                                                                                                  
 831      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 832      * a configuration step, this allows the proper animations to run after other transitions.           
 833      */                                                                                                  
 834     private long completeAdd(PendingAddArguments args) {                                                 
 835         long screenId = args.screenId;                                                                   
 836         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 837             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 838             // that the drop page actually exists.                                                       
 839             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 840         }                                                                                                
 841                                                                                                          
 842         switch (args.requestCode) {                                                                      
 843             case REQUEST_CREATE_SHORTCUT:                                                                
 844                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 845                         args.cellY);                                                                     
 846                 break;                                                                                   
 847             case REQUEST_CREATE_APPWIDGET:                                                               
 848                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 849                 break;                                                                                   
 850             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 851                 completeRestoreAppWidget(args.appWidgetId);                                              
 852                 break;                                                                                   
 853         }                                                                                                
 854         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 855         // if you turned the screen off and then back while in All Apps, Launcher would not              
 856         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 857         resetAddInfo();                                                                                  
 858         return screenId;                                                                                 
 859     }                                                                                                    
 860                                                                                                          
 861     @Override                                                                                            
 862     protected void onActivityResult(                                                                     
 863             final int requestCode, final int resultCode, final Intent data) {                            
 864         // Reset the startActivity waiting flag                                                          
 865         setWaitingForResult(false);                                                                      
 866         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 867         mPendingAddWidgetId = -1;                                                                        
 868                                                                                                          
 869         Runnable exitSpringLoaded = new Runnable() {                                                     
 870             @Override                                                                                    
 871             public void run() {                                                                          
 872                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 873                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 874             }                                                                                            
 875         };                                                                                               
 876                                                                                                          
 877         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 878             final int appWidgetId = data != null ?                                                       
 879                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 880             if (resultCode == RESULT_CANCELED) {                                                         
 881                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 882                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 883                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 884             } else if (resultCode == RESULT_OK) {                                                        
 885                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 886                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 887             }                                                                                            
 888             return;                                                                                      
 889         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 890             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 891                 mWorkspace.exitOverviewMode(false);                                                      
 892             }                                                                                            
 893             return;                                                                                      
 894         }                                                                                                
 895                                                                                                          
 896         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 897                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 898                                                                                                          
 899         final boolean workspaceLocked = isWorkspaceLocked();                                             
 900         // We have special handling for widgets                                                          
 901         if (isWidgetDrop) {                                                                              
 902             final int appWidgetId;                                                                       
 903             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 904                     : -1;                                                                                
 905             if (widgetId < 0) {                                                                          
 906                 appWidgetId = pendingAddWidgetId;                                                        
 907             } else {                                                                                     
 908                 appWidgetId = widgetId;                                                                  
 909             }                                                                                            
 910                                                                                                          
 911             final int result;                                                                            
 912             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 913                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 914                         "returned from the widget configuration activity.");                             
 915                 result = RESULT_CANCELED;                                                                
 916                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 917                 final Runnable onComplete = new Runnable() {                                             
 918                     @Override                                                                            
 919                     public void run() {                                                                  
 920                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 921                     }                                                                                    
 922                 };                                                                                       
 923                 if (workspaceLocked) {                                                                   
 924                     // No need to remove the empty screen if we're mid-binding, as the                   
 925                     // the bind will not add the empty screen.                                           
 926                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 927                 } else {                                                                                 
 928                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 929                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 930                 }                                                                                        
 931             } else {                                                                                     
 932                 if (!workspaceLocked) {                                                                  
 933                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 934                         // When the screen id represents an actual screen (as opposed to a rank)         
 935                         // we make sure that the drop page actually exists.                              
 936                         mPendingAddInfo.screenId =                                                       
 937                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 938                     }                                                                                    
 939                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 940                                                                                                          
 941                     dropLayout.setDropPending(true);                                                     
 942                     final Runnable onComplete = new Runnable() {                                         
 943                         @Override                                                                        
 944                         public void run() {                                                              
 945                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 946                             dropLayout.setDropPending(false);                                            
 947                         }                                                                                
 948                     };                                                                                   
 949                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 950                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 951                 } else {                                                                                 
 952                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 953                             mPendingAddInfo);                                                            
 954                     sPendingAddItem = args;                                                              
 955                 }                                                                                        
 956             }                                                                                            
 957             return;                                                                                      
 958         }                                                                                                
 959                                                                                                          
 960         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 961             if (resultCode == RESULT_OK) {                                                               
 962                 // Update the widget view.                                                               
 963                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 964                         pendingAddWidgetId, mPendingAddInfo);                                            
 965                 if (workspaceLocked) {                                                                   
 966                     sPendingAddItem = args;                                                              
 967                 } else {                                                                                 
 968                     completeAdd(args);                                                                   
 969                 }                                                                                        
 970             }                                                                                            
 971             // Leave the widget in the pending state if the user canceled the configure.                 
 972             return;                                                                                      
 973         }                                                                                                
 974                                                                                                          
 975         // The pattern used here is that a user PICKs a specific application,                            
 976         // which, depending on the target, might need to CREATE the actual target.                       
 977                                                                                                          
 978         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 979         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 980         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 981             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 982                     mPendingAddInfo);                                                                    
 983             if (isWorkspaceLocked()) {                                                                   
 984                 sPendingAddItem = args;                                                                  
 985             } else {                                                                                     
 986                 completeAdd(args);                                                                       
 987                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 988                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 989             }                                                                                            
 990         } else if (resultCode == RESULT_CANCELED) {                                                      
 991             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 992                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 993         }                                                                                                
 994         mDragLayer.clearAnimatedView();                                                                  
 995     }                                                                                                    
 996                                                                                                          
 997     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 998             appWidgetId, ItemInfo info) {                                                                
 999         PendingAddArguments args = new PendingAddArguments();                                            
1000         args.requestCode = requestCode;                                                                  
1001         args.intent = data;                                                                              
1002         args.container = info.container;                                                                 
1003         args.screenId = info.screenId;                                                                   
1004         args.cellX = info.cellX;                                                                         
1005         args.cellY = info.cellY;                                                                         
1006         args.appWidgetId = appWidgetId;                                                                  
1007         return args;                                                                                     
1008     }                                                                                                    
1009                                                                                                          
1010     /**                                                                                                  
1011      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
1012      *                                                                                                   
1013      * @param screenId the screen id to check                                                            
1014      * @return the new screen, or screenId if it exists                                                  
1015      */                                                                                                  
1016     private long ensurePendingDropLayoutExists(long screenId) {                                          
1017         CellLayout dropLayout =                                                                          
1018                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
1019         if (dropLayout == null) {                                                                        
1020             // it's possible that the add screen was removed because it was                              
1021             // empty and a re-bind occurred                                                              
1022             mWorkspace.addExtraEmptyScreen();                                                            
1023             return mWorkspace.commitExtraEmptyScreen();                                                  
1024         } else {                                                                                         
1025             return screenId;                                                                             
1026         }                                                                                                
1027     }                                                                                                    
1028                                                                                                          
1029     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
1030         CellLayout cellLayout =                                                                          
1031                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
1032         Runnable onCompleteRunnable = null;                                                              
1033         int animationType = 0;                                                                           
1034                                                                                                          
1035         AppWidgetHostView boundWidget = null;                                                            
1036         if (resultCode == RESULT_OK) {                                                                   
1037             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
1038             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
1039                     mPendingAddWidgetInfo);                                                              
1040             boundWidget = layout;                                                                        
1041             onCompleteRunnable = new Runnable() {                                                        
1042                 @Override                                                                                
1043                 public void run() {                                                                      
1044                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
1045                             mPendingAddInfo.screenId, layout, null);                                     
1046                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
1047                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
1048                 }                                                                                        
1049             };                                                                                           
1050         } else if (resultCode == RESULT_CANCELED) {                                                      
1051             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
1052             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
1053         }                                                                                                
1054         if (mDragLayer.getAnimatedView() != null) {                                                      
1055             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
1056                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
1057                     animationType, boundWidget, true);                                                   
1058         } else if (onCompleteRunnable != null) {                                                         
1059             // The animated view may be null in the case of a rotation during widget configuration       
1060             onCompleteRunnable.run();                                                                    
1061         }                                                                                                
1062     }                                                                                                    
1063                                                                                                          
1064     @Override                                                                                            
1065     protected void onStop() {                                                                            
1066         super.onStop();                                                                                  
1067         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1068     }                                                                                                    
1069                                                                                                          
1070     @Override                                                                                            
1071     protected void onStart() {                                                                           
1072         super.onStart();                                                                                 
1073         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1074     }                                                                                                    
1075                                                                                                          
1076     @Override                                                                                            
1077     protected void onResume() {                                                                          
1078         long startTime = 0;                                                                              
1079         if (DEBUG_RESUME_TIME) {                                                                         
1080             startTime = System.currentTimeMillis();                                                      
1081             Log.v(TAG, "Launcher.onResume()");                                                           
1082         }                                                                                                
1083         super.onResume();                                                                                
1084                                                                                                          
1085         // Restore the previous launcher state                                                           
1086         if (mOnResumeState == State.WORKSPACE) {                                                         
1087             showWorkspace(false);                                                                        
1088         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                             
1089             showAllApps(false, mAppsCustomizeContent.getContentType(), false);                           
1090         }                                                                                                
1091         mOnResumeState = State.NONE;                                                                     
1092                                                                                                          
1093         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1094         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1095                                                                                                          
1096         mPaused = false;                                                                                 
1097         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1098             setWorkspaceLoading(true);                                                                   
1099             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1100             mRestoring = false;                                                                          
1101             mOnResumeNeedsLoad = false;                                                                  
1102         }                                                                                                
1103         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1104             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1105             // execute them here                                                                         
1106             long startTimeCallbacks = 0;                                                                 
1107             if (DEBUG_RESUME_TIME) {                                                                     
1108                 startTimeCallbacks = System.currentTimeMillis();                                         
1109             }                                                                                            
1110                                                                                                          
1111             if (mAppsCustomizeContent != null) {                                                         
1112                 mAppsCustomizeContent.setBulkBind(true);                                                 
1113             }                                                                                            
1114             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1115                 mBindOnResumeCallbacks.get(i).run();                                                     
1116             }                                                                                            
1117             if (mAppsCustomizeContent != null) {                                                         
1118                 mAppsCustomizeContent.setBulkBind(false);                                                
1119             }                                                                                            
1120             mBindOnResumeCallbacks.clear();                                                              
1121             if (DEBUG_RESUME_TIME) {                                                                     
1122                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1123                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1124             }                                                                                            
1125         }                                                                                                
1126         if (mOnResumeCallbacks.size() > 0) {                                                             
1127             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1128                 mOnResumeCallbacks.get(i).run();                                                         
1129             }                                                                                            
1130             mOnResumeCallbacks.clear();                                                                  
1131         }                                                                                                
1132                                                                                                          
1133         // Reset the pressed state of icons that were locked in the press state while activities         
1134         // were launching                                                                                
1135         if (mWaitingForResume != null) {                                                                 
1136             // Resets the previous workspace icon press state                                            
1137             mWaitingForResume.setStayPressed(false);                                                     
1138         }                                                                                                
1139                                                                                                          
1140         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1141         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1142         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1143         // orientation.                                                                                  
1144         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1145                                                                                                          
1146         // Process any items that were added while Launcher was away.                                    
1147         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1148                                                                                                          
1149         // Update the voice search button proxy                                                          
1150         updateVoiceButtonProxyVisible(false);                                                            
1151                                                                                                          
1152         // Again, as with the above scenario, it's possible that one or more of the global icons         
1153         // were updated in the wrong orientation.                                                        
1154         updateGlobalIcons();                                                                             
1155         if (DEBUG_RESUME_TIME) {                                                                         
1156             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1157         }                                                                                                
1158                                                                                                          
1159         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1160             // If we are resuming and the custom content is the current page, we call onShow().          
1161             // It is also poassible that onShow will instead be called slightly after first layout       
1162             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1163             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1164                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1165             }                                                                                            
1166         }                                                                                                
1167         mWorkspace.updateInteractionForState();                                                          
1168         mWorkspace.onResume();                                                                           
1169                                                                                                          
1170         PackageInstallerCompat.getInstance(this).onResume();                                             
1171     }                                                                                                    
1172                                                                                                          
1173     @Override                                                                                            
1174     protected void onPause() {                                                                           
1175         // Ensure that items added to Launcher are queued until Launcher returns                         
1176         InstallShortcutReceiver.enableInstallQueue();                                                    
1177         PackageInstallerCompat.getInstance(this).onPause();                                              
1178                                                                                                          
1179         super.onPause();                                                                                 
1180         mPaused = true;                                                                                  
1181         mDragController.cancelDrag();                                                                    
1182         mDragController.resetLastGestureUpTime();                                                        
1183                                                                                                          
1184         // We call onHide() aggressively. The custom content callbacks should be able to                 
1185         // debounce excess onHide calls.                                                                 
1186         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1187             mWorkspace.getCustomContentCallbacks().onHide();                                             
1188         }                                                                                                
1189     }                                                                                                    
1190                                                                                                          
1191     QSBScroller mQsbScroller = new QSBScroller() {                                                       
1192         int scrollY = 0;                                                                                 
1193                                                                                                          
1194         @Override                                                                                        
1195         public void setScrollY(int scroll) {                                                             
1196             scrollY = scroll;                                                                            
1197                                                                                                          
1198             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1199                 mSearchDropTargetBar.setTranslationY(- scrollY);                                         
1200                 getQsbBar().setTranslationY(-scrollY);                                                   
1201             }                                                                                            
1202         }                                                                                                
1203     };                                                                                                   
1204                                                                                                          
1205     public void resetQSBScroll() {                                                                       
1206         mSearchDropTargetBar.animate().translationY(0).start();                                          
1207         getQsbBar().animate().translationY(0).start();                                                   
1208     }                                                                                                    
1209                                                                                                          
1210     public interface CustomContentCallbacks {                                                            
1211         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1212         // by a onResume or by scrolling otherwise.                                                      
1213         public abstract void onShow(boolean fromResume);                                                 
1214                                                                                                          
1215         // Custom content is completely hidden                                                           
1216         public abstract void onHide();                                                                   
1217                                                                                                          
1218         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1219         public abstract void onScrollProgressChanged(float progress);                                    
1220                                                                                                          
1221         // Indicates whether the user is allowed to scroll away from the custom content.                 
1222         public abstract boolean isScrollingAllowed();                                                    
1223     }                                                                                                    
1224                                                                                                          
1225     protected boolean hasSettings() {                                                                    
1226         return false;                                                                                    
1227     }                                                                                                    
1228                                                                                                          
1229     public interface QSBScroller {                                                                       
1230         public abstract void setScrollY(int scrollY);                                                    
1231     }                                                                                                    
1232                                                                                                          
1233     public QSBScroller addToCustomContentPage(View customContent,                                        
1234             CustomContentCallbacks callbacks, String description) {                                      
1235         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1236         return mQsbScroller;                                                                             
1237     }                                                                                                    
1238                                                                                                          
1239     // The custom content needs to offset its content to account for the QSB                             
1240     public int getTopOffsetForCustomContent() {                                                          
1241         return mWorkspace.getPaddingTop();                                                               
1242     }                                                                                                    
1243                                                                                                          
1244     @Override                                                                                            
1245     public Object onRetainNonConfigurationInstance() {                                                   
1246         // Flag the loader to stop early before switching                                                
1247         if (mModel.isCurrentCallbacks(this)) {                                                           
1248             mModel.stopLoader();                                                                         
1249         }                                                                                                
1250         if (mAppsCustomizeContent != null) {                                                             
1251             mAppsCustomizeContent.surrender();                                                           
1252         }                                                                                                
1253         return Boolean.TRUE;                                                                             
1254     }                                                                                                    
1255                                                                                                          
1256     // We can't hide the IME if it was forced open.  So don't bother                                     
1257     @Override                                                                                            
1258     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1259         super.onWindowFocusChanged(hasFocus);                                                            
1260         mHasFocus = hasFocus;                                                                            
1261     }                                                                                                    
1262                                                                                                          
1263     private boolean acceptFilter() {                                                                     
1264         final InputMethodManager inputManager = (InputMethodManager)                                     
1265                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1266         return !inputManager.isFullscreenMode();                                                         
1267     }                                                                                                    
1268                                                                                                          
1269     @Override                                                                                            
1270     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1271         final int uniChar = event.getUnicodeChar();                                                      
1272         final boolean handled = super.onKeyDown(keyCode, event);                                         
1273         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1274         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1275             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1276                     keyCode, event);                                                                     
1277             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1278                 // something usable has been typed - start a search                                      
1279                 // the typed text will be retrieved and cleared by                                       
1280                 // showSearchDialog()                                                                    
1281                 // If there are multiple keystrokes before the search dialog takes focus,                
1282                 // onSearchRequested() will be called for every keystroke,                               
1283                 // but it is idempotent, so it's fine.                                                   
1284                 return onSearchRequested();                                                              
1285             }                                                                                            
1286         }                                                                                                
1287                                                                                                          
1288         // Eat the long press event so the keyboard doesn't come up.                                     
1289         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1290             return true;                                                                                 
1291         }                                                                                                
1292                                                                                                          
1293         return handled;                                                                                  
1294     }                                                                                                    
1295                                                                                                          
1296     private String getTypedText() {                                                                      
1297         return mDefaultKeySsb.toString();                                                                
1298     }                                                                                                    
1299                                                                                                          
1300     private void clearTypedText() {                                                                      
1301         mDefaultKeySsb.clear();                                                                          
1302         mDefaultKeySsb.clearSpans();                                                                     
1303         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1304     }                                                                                                    
1305                                                                                                          
1306     /**                                                                                                  
1307      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1308      * State                                                                                             
1309      */                                                                                                  
1310     private static State intToState(int stateOrdinal) {                                                  
1311         State state = State.WORKSPACE;                                                                   
1312         final State[] stateValues = State.values();                                                      
1313         for (int i = 0; i < stateValues.length; i++) {                                                   
1314             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1315                 state = stateValues[i];                                                                  
1316                 break;                                                                                   
1317             }                                                                                            
1318         }                                                                                                
1319         return state;                                                                                    
1320     }                                                                                                    
1321                                                                                                          
1322     /**                                                                                                  
1323      * Restores the previous state, if it exists.                                                        
1324      *                                                                                                   
1325      * @param savedState The previous state.                                                             
1326      */                                                                                                  
1327     @SuppressWarnings("unchecked")                                                                       
1328     private void restoreState(Bundle savedState) {                                                       
1329         if (savedState == null) {                                                                        
1330             return;                                                                                      
1331         }                                                                                                
1332                                                                                                          
1333         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1334         if (state == State.APPS_CUSTOMIZE) {                                                             
1335             mOnResumeState = State.APPS_CUSTOMIZE;                                                       
1336         }                                                                                                
1337                                                                                                          
1338         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1339                 PagedView.INVALID_RESTORE_PAGE);                                                         
1340         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1341             mWorkspace.setRestorePage(currentScreen);                                                    
1342         }                                                                                                
1343                                                                                                          
1344         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1345         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1346                                                                                                          
1347         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1348             mPendingAddInfo.container = pendingAddContainer;                                             
1349             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1350             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1351             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1352             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1353             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1354             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1355             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1356             setWaitingForResult(true);                                                                   
1357             mRestoring = true;                                                                           
1358         }                                                                                                
1359                                                                                                          
1360         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1361         if (renameFolder) {                                                                              
1362             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1363             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1364             mRestoring = true;                                                                           
1365         }                                                                                                
1366                                                                                                          
1367         // Restore the AppsCustomize tab                                                                 
1368         if (mAppsCustomizeTabHost != null) {                                                             
1369             String curTab = savedState.getString("apps_customize_currentTab");                           
1370             if (curTab != null) {                                                                        
1371                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1372                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1373                 mAppsCustomizeContent.loadAssociatedPages(                                               
1374                         mAppsCustomizeContent.getCurrentPage());                                         
1375             }                                                                                            
1376                                                                                                          
1377             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1378             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1379         }                                                                                                
1380         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1381                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1382     }                                                                                                    
1383                                                                                                          
1384     /**                                                                                                  
1385      * Finds all the views we need and configure them properly.                                          
1386      */                                                                                                  
1387     private void setupViews() {                                                                          
1388         final DragController dragController = mDragController;                                           
1389                                                                                                          
1390         mLauncherView = findViewById(R.id.launcher);                                                     
1391         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1392         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1393         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1394         mWorkspace.setPageSwitchListener(this);                                                          
1395         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1396                                                                                                          
1397         mLauncherView.setSystemUiVisibility(                                                             
1398                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1399         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1400                                                                                                          
1401         // Setup the drag layer                                                                          
1402         mDragLayer.setup(this, dragController);                                                          
1403                                                                                                          
1404         // Setup the hotseat                                                                             
1405         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1406         if (mHotseat != null) {                                                                          
1407             mHotseat.setup(this);                                                                        
1408             mHotseat.setOnLongClickListener(this);                                                       
1409         }                                                                                                
1410                                                                                                          
1411         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1412         View widgetButton = findViewById(R.id.widget_button);                                            
1413         widgetButton.setOnClickListener(new OnClickListener() {                                          
1414             @Override                                                                                    
1415             public void onClick(View arg0) {                                                             
1416                 if (!mWorkspace.isSwitchingState()) {                                                    
1417                     onClickAddWidgetButton(arg0);                                                        
1418                 }                                                                                        
1419             }                                                                                            
1420         });                                                                                              
1421         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1422                                                                                                          
1423         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1424         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1425             @Override                                                                                    
1426             public void onClick(View arg0) {                                                             
1427                 if (!mWorkspace.isSwitchingState()) {                                                    
1428                     onClickWallpaperPicker(arg0);                                                        
1429                 }                                                                                        
1430             }                                                                                            
1431         });                                                                                              
1432         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1433                                                                                                          
1434         View settingsButton = findViewById(R.id.settings_button);                                        
1435         if (hasSettings()) {                                                                             
1436             settingsButton.setOnClickListener(new OnClickListener() {                                    
1437                 @Override                                                                                
1438                 public void onClick(View arg0) {                                                         
1439                     if (!mWorkspace.isSwitchingState()) {                                                
1440                         onClickSettingsButton(arg0);                                                     
1441                     }                                                                                    
1442                 }                                                                                        
1443             });                                                                                          
1444             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1445         } else {                                                                                         
1446             settingsButton.setVisibility(View.GONE);                                                     
1447             FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();     
1448             lp.gravity = Gravity.END | Gravity.TOP;                                                      
1449             widgetButton.requestLayout();                                                                
1450         }                                                                                                
1451                                                                                                          
1452         mOverviewPanel.setAlpha(0f);                                                                     
1453                                                                                                          
1454         // Setup the workspace                                                                           
1455         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1456         mWorkspace.setOnLongClickListener(this);                                                         
1457         mWorkspace.setup(dragController);                                                                
1458         dragController.addDragListener(mWorkspace);                                                      
1459                                                                                                          
1460         // Get the search/delete bar                                                                     
1461         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1462                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1463                                                                                                          
1464         // Setup AppsCustomize                                                                           
1465         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1466         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1467                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1468         mAppsCustomizeContent.setup(this, dragController);                                               
1469                                                                                                          
1470         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1471         dragController.setDragScoller(mWorkspace);                                                       
1472         dragController.setScrollView(mDragLayer);                                                        
1473         dragController.setMoveTarget(mWorkspace);                                                        
1474         dragController.addDropTarget(mWorkspace);                                                        
1475         if (mSearchDropTargetBar != null) {                                                              
1476             mSearchDropTargetBar.setup(this, dragController);                                            
1477         }                                                                                                
1478                                                                                                          
1479         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1480             Log.v(TAG, "adding WeightWatcher");                                                          
1481             mWeightWatcher = new WeightWatcher(this);                                                    
1482             mWeightWatcher.setAlpha(0.5f);                                                               
1483             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1484                     new FrameLayout.LayoutParams(                                                        
1485                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1486                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1487                             Gravity.BOTTOM)                                                              
1488             );                                                                                           
1489                                                                                                          
1490             boolean show = shouldShowWeightWatcher();                                                    
1491             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1492         }                                                                                                
1493     }                                                                                                    
1494                                                                                                          
1495     /**                                                                                                  
1496      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1497      */                                                                                                  
1498     public void setAllAppsButton(View allAppsButton) {                                                   
1499         mAllAppsButton = allAppsButton;                                                                  
1500     }                                                                                                    
1501                                                                                                          
1502     public View getAllAppsButton() {                                                                     
1503         return mAllAppsButton;                                                                           
1504     }                                                                                                    
1505                                                                                                          
1506     /**                                                                                                  
1507      * Creates a view representing a shortcut.                                                           
1508      *                                                                                                   
1509      * @param info The data structure describing the shortcut.                                           
1510      *                                                                                                   
1511      * @return A View inflated from R.layout.application.                                                
1512      */                                                                                                  
1513     View createShortcut(ShortcutInfo info) {                                                             
1514         return createShortcut(R.layout.application,                                                      
1515                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1516     }                                                                                                    
1517                                                                                                          
1518     /**                                                                                                  
1519      * Creates a view representing a shortcut inflated from the specified resource.                      
1520      *                                                                                                   
1521      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1522      * @param parent The group the shortcut belongs to.                                                  
1523      * @param info The data structure describing the shortcut.                                           
1524      *                                                                                                   
1525      * @return A View inflated from layoutResId.                                                         
1526      */                                                                                                  
1527     View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                          
1528         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1529         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1530         favorite.setOnClickListener(this);                                                               
1531         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1532         return favorite;                                                                                 
1533     }                                                                                                    
1534                                                                                                          
1535     /**                                                                                                  
1536      * Add a shortcut to the workspace.                                                                  
1537      *                                                                                                   
1538      * @param data The intent describing the shortcut.                                                   
1539      * @param cellInfo The position on screen where to create the shortcut.                              
1540      */                                                                                                  
1541     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1542             int cellY) {                                                                                 
1543         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1544         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1545         CellLayout layout = getCellLayout(container, screenId);                                          
1546                                                                                                          
1547         boolean foundCellSpan = false;                                                                   
1548                                                                                                          
1549         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                             
1550         if (info == null) {                                                                              
1551             return;                                                                                      
1552         }                                                                                                
1553         final View view = createShortcut(info);                                                          
1554                                                                                                          
1555         // First we check if we already know the exact location where we want to add this item.          
1556         if (cellX >= 0 && cellY >= 0) {                                                                  
1557             cellXY[0] = cellX;                                                                           
1558             cellXY[1] = cellY;                                                                           
1559             foundCellSpan = true;                                                                        
1560                                                                                                          
1561             // If appropriate, either create a folder or add to an existing folder                       
1562             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1563                     true, null,null)) {                                                                  
1564                 return;                                                                                  
1565             }                                                                                            
1566             DragObject dragObject = new DragObject();                                                    
1567             dragObject.dragInfo = info;                                                                  
1568             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1569                     true)) {                                                                             
1570                 return;                                                                                  
1571             }                                                                                            
1572         } else if (touchXY != null) {                                                                    
1573             // when dragging and dropping, just find the closest free spot                               
1574             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1575             foundCellSpan = (result != null);                                                            
1576         } else {                                                                                         
1577             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1578         }                                                                                                
1579                                                                                                          
1580         if (!foundCellSpan) {                                                                            
1581             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1582             return;                                                                                      
1583         }                                                                                                
1584                                                                                                          
1585         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1586                                                                                                          
1587         if (!mRestoring) {                                                                               
1588             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1589                     isWorkspaceLocked());                                                                
1590         }                                                                                                
1591     }                                                                                                    
1592                                                                                                          
1593     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1594             int minHeight) {                                                                             
1595         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1596         // We want to account for the extra amount of padding that we are adding to the widget           
1597         // to ensure that it gets the full amount of space that it has requested                         
1598         int requiredWidth = minWidth + padding.left + padding.right;                                     
1599         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1600         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1601     }                                                                                                    
1602                                                                                                          
1603     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1604         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1605     }                                                                                                    
1606                                                                                                          
1607     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1608         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1609     }                                                                                                    
1610                                                                                                          
1611     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1612         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1613     }                                                                                                    
1614                                                                                                          
1615     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1616         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1617                 info.minResizeHeight);                                                                   
1618     }                                                                                                    
1619                                                                                                          
1620     /**                                                                                                  
1621      * Add a widget to the workspace.                                                                    
1622      *                                                                                                   
1623      * @param appWidgetId The app widget id                                                              
1624      * @param cellInfo The position on screen where to create the widget.                                
1625      */                                                                                                  
1626     private void completeAddAppWidget(final int appWidgetId, long container, long screenId,              
1627             AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                           
1628         if (appWidgetInfo == null) {                                                                     
1629             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
1630         }                                                                                                
1631                                                                                                          
1632         // Calculate the grid spans needed to fit this widget                                            
1633         CellLayout layout = getCellLayout(container, screenId);                                          
1634                                                                                                          
1635         int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                      
1636         int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                            
1637                                                                                                          
1638         // Try finding open space on Launcher screen                                                     
1639         // We have saved the position to which the widget was dragged-- this really only matters         
1640         // if we are placing widgets on a "spring-loaded" screen                                         
1641         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1642         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1643         int[] finalSpan = new int[2];                                                                    
1644         boolean foundCellSpan = false;                                                                   
1645         if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                  
1646             cellXY[0] = mPendingAddInfo.cellX;                                                           
1647             cellXY[1] = mPendingAddInfo.cellY;                                                           
1648             spanXY[0] = mPendingAddInfo.spanX;                                                           
1649             spanXY[1] = mPendingAddInfo.spanY;                                                           
1650             foundCellSpan = true;                                                                        
1651         } else if (touchXY != null) {                                                                    
1652             // when dragging and dropping, just find the closest free spot                               
1653             int[] result = layout.findNearestVacantArea(                                                 
1654                     touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                       
1655                     spanXY[1], cellXY, finalSpan);                                                       
1656             spanXY[0] = finalSpan[0];                                                                    
1657             spanXY[1] = finalSpan[1];                                                                    
1658             foundCellSpan = (result != null);                                                            
1659         } else {                                                                                         
1660             foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                  
1661         }                                                                                                
1662                                                                                                          
1663         if (!foundCellSpan) {                                                                            
1664             if (appWidgetId != -1) {                                                                     
1665                 // Deleting an app widget ID is a void call but writes to disk before returning          
1666                 // to the caller...                                                                      
1667                 new AsyncTask<Void, Void, Void>() {                                                      
1668                     public Void doInBackground(Void ... args) {                                          
1669                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                   
1670                         return null;                                                                     
1671                     }                                                                                    
1672                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                        
1673             }                                                                                            
1674             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1675             return;                                                                                      
1676         }                                                                                                
1677                                                                                                          
1678         // Build Launcher-specific widget info and save to database                                      
1679         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                      
1680                 appWidgetInfo.provider);                                                                 
1681         launcherInfo.spanX = spanXY[0];                                                                  
1682         launcherInfo.spanY = spanXY[1];                                                                  
1683         launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                
1684         launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                
1685         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1686                                                                                                          
1687         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1688                 container, screenId, cellXY[0], cellXY[1], false);                                       
1689                                                                                                          
1690         if (!mRestoring) {                                                                               
1691             if (hostView == null) {                                                                      
1692                 // Perform actual inflation because we're live                                           
1693                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1694                 launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                          
1695             } else {                                                                                     
1696                 // The AppWidgetHostView has already been inflated and instantiated                      
1697                 launcherInfo.hostView = hostView;                                                        
1698             }                                                                                            
1699                                                                                                          
1700             launcherInfo.hostView.setTag(launcherInfo);                                                  
1701             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1702             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1703                                                                                                          
1704             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],     
1705                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                        
1706                                                                                                          
1707             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1708         }                                                                                                
1709         resetAddInfo();                                                                                  
1710     }                                                                                                    
1711                                                                                                          
1712     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1713         @Override                                                                                        
1714         public void onReceive(Context context, Intent intent) {                                          
1715             final String action = intent.getAction();                                                    
1716             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1717                 mUserPresent = false;                                                                    
1718                 mDragLayer.clearAllResizeFrames();                                                       
1719                 updateRunning();                                                                         
1720                 // Reset AllApps to its initial state only if we are not in the middle of                
1721                 // processing a multi-step drop                                                          
1722                 if ((mAppsCustomizeTabHost != null) && (mPendingAddInfo.container == ItemInfo.NO_ID)) {  
1723                     showWorkspace(false);                                                                
1724                 }                                                                                        
1725             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1726                 mUserPresent = true;                                                                     
1727                 updateRunning();                                                                         
1728             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1729                 mModel.resetLoadedState(false, true);                                                    
1730                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1731             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1732                 mModel.resetLoadedState(false, true);                                                    
1733                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1734             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action) || LauncherAppsComp🔵
1735                 getModel().forceReload();                                                                
1736             }                                                                                            
1737         }                                                                                                
1738     };                                                                                                   
1739                                                                                                          
1740     @Override                                                                                            
1741     public void onAttachedToWindow() {                                                                   
1742         super.onAttachedToWindow();                                                                      
1743                                                                                                          
1744         // Listen for broadcasts related to user-presence                                                
1745         final IntentFilter filter = new IntentFilter();                                                  
1746         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1747         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1748         // For handling managed profiles                                                                 
1749         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1750         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1751         if (ENABLE_DEBUG_INTENTS) {                                                                      
1752             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1753             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1754         }                                                                                                
1755         registerReceiver(mReceiver, filter);                                                             
1756         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1757         setupTransparentSystemBarsForLmp();                                                              
1758         mAttached = true;                                                                                
1759         mVisible = true;                                                                                 
1760     }                                                                                                    
1761                                                                                                          
1762     /**                                                                                                  
1763      * Sets up transparent navigation and status bars in LMP.                                            
1764      * This method is a no-op for other platform versions.                                               
1765      */                                                                                                  
1766     @TargetApi(19)                                                                                       
1767     private void setupTransparentSystemBarsForLmp() {                                                    
1768         // TODO(sansid): use the APIs directly when compiling against L sdk.                             
1769         // Currently we use reflection to access the flags and the API to set the transparency           
1770         // on the System bars.                                                                           
1771         if (Utilities.isLmpOrAbove()) {                                                                  
1772             try {                                                                                        
1773                 getWindow().getAttributes().systemUiVisibility |=                                        
1774                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1775                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1776                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1777                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                
1778                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1779                 Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(              
1780                         "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                            
1781                 getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                             
1782                                                                                                          
1783                 Method setStatusBarColorMethod =                                                         
1784                         Window.class.getDeclaredMethod("setStatusBarColor", int.class);                  
1785                 Method setNavigationBarColorMethod =                                                     
1786                         Window.class.getDeclaredMethod("setNavigationBarColor", int.class);              
1787                 setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                          
1788                 setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                      
1789             } catch (NoSuchFieldException e) {                                                           
1790                 Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                    
1791             } catch (NoSuchMethodException ex) {                                                         
1792                 Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                   
1793             } catch (IllegalAccessException e) {                                                         
1794                 Log.w(TAG, "IllegalAccessException while setting up transparent bars");                  
1795             } catch (IllegalArgumentException e) {                                                       
1796                 Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                
1797             } catch (InvocationTargetException e) {                                                      
1798                 Log.w(TAG, "InvocationTargetException while setting up transparent bars");               
1799             } finally {}                                                                                 
1800         }                                                                                                
1801     }                                                                                                    
1802                                                                                                          
1803     @Override                                                                                            
1804     public void onDetachedFromWindow() {                                                                 
1805         super.onDetachedFromWindow();                                                                    
1806         mVisible = false;                                                                                
1807                                                                                                          
1808         if (mAttached) {                                                                                 
1809             unregisterReceiver(mReceiver);                                                               
1810             mAttached = false;                                                                           
1811         }                                                                                                
1812         updateRunning();                                                                                 
1813     }                                                                                                    
1814                                                                                                          
1815     public void onWindowVisibilityChanged(int visibility) {                                              
1816         mVisible = visibility == View.VISIBLE;                                                           
1817         updateRunning();                                                                                 
1818         // The following code used to be in onResume, but it turns out onResume is called when           
1819         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1820         // is a more appropriate event to handle                                                         
1821         if (mVisible) {                                                                                  
1822             mAppsCustomizeTabHost.onWindowVisible();                                                     
1823             if (!mWorkspaceLoading) {                                                                    
1824                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1825                 // We want to let Launcher draw itself at least once before we force it to build         
1826                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1827                 // apps is nice and speedy.                                                              
1828                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1829                     private boolean mStarted = false;                                                    
1830                     public void onDraw() {                                                               
1831                         if (mStarted) return;                                                            
1832                         mStarted = true;                                                                 
1833                         // We delay the layer building a bit in order to give                            
1834                         // other message processing a time to run.  In particular                        
1835                         // this avoids a delay in hiding the IME if it was                               
1836                         // currently shown, because doing that may involve                               
1837                         // some communication back with the app.                                         
1838                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1839                         final ViewTreeObserver.OnDrawListener listener = this;                           
1840                         mWorkspace.post(new Runnable() {                                                 
1841                                 public void run() {                                                      
1842                                     if (mWorkspace != null &&                                            
1843                                             mWorkspace.getViewTreeObserver() != null) {                  
1844                                         mWorkspace.getViewTreeObserver().                                
1845                                                 removeOnDrawListener(listener);                          
1846                                     }                                                                    
1847                                 }                                                                        
1848                             });                                                                          
1849                         return;                                                                          
1850                     }                                                                                    
1851                 });                                                                                      
1852             }                                                                                            
1853             clearTypedText();                                                                            
1854         }                                                                                                
1855     }                                                                                                    
1856                                                                                                          
1857     private void sendAdvanceMessage(long delay) {                                                        
1858         mHandler.removeMessages(ADVANCE_MSG);                                                            
1859         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1860         mHandler.sendMessageDelayed(msg, delay);                                                         
1861         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1862     }                                                                                                    
1863                                                                                                          
1864     private void updateRunning() {                                                                       
1865         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1866         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1867             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1868             if (autoAdvanceRunning) {                                                                    
1869                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1870                 sendAdvanceMessage(delay);                                                               
1871             } else {                                                                                     
1872                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1873                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1874                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1875                 }                                                                                        
1876                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1877                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1878             }                                                                                            
1879         }                                                                                                
1880     }                                                                                                    
1881                                                                                                          
1882     private final Handler mHandler = new Handler() {                                                     
1883         @Override                                                                                        
1884         public void handleMessage(Message msg) {                                                         
1885             if (msg.what == ADVANCE_MSG) {                                                               
1886                 int i = 0;                                                                               
1887                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1888                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1889                     final int delay = mAdvanceStagger * i;                                               
1890                     if (v instanceof Advanceable) {                                                      
1891                        postDelayed(new Runnable() {                                                      
1892                            public void run() {                                                           
1893                                ((Advanceable) v).advance();                                              
1894                            }                                                                             
1895                        }, delay);                                                                        
1896                     }                                                                                    
1897                     i++;                                                                                 
1898                 }                                                                                        
1899                 sendAdvanceMessage(mAdvanceInterval);                                                    
1900             }                                                                                            
1901         }                                                                                                
1902     };                                                                                                   
1903                                                                                                          
1904     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1905         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1906         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1907         if (v instanceof Advanceable) {                                                                  
1908             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1909             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1910             updateRunning();                                                                             
1911         }                                                                                                
1912     }                                                                                                    
1913                                                                                                          
1914     void removeWidgetToAutoAdvance(View hostView) {                                                      
1915         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1916             mWidgetsToAdvance.remove(hostView);                                                          
1917             updateRunning();                                                                             
1918         }                                                                                                
1919     }                                                                                                    
1920                                                                                                          
1921     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1922         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1923         launcherInfo.hostView = null;                                                                    
1924     }                                                                                                    
1925                                                                                                          
1926     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1927         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1928         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1929     }                                                                                                    
1930                                                                                                          
1931     public DragLayer getDragLayer() {                                                                    
1932         return mDragLayer;                                                                               
1933     }                                                                                                    
1934                                                                                                          
1935     public Workspace getWorkspace() {                                                                    
1936         return mWorkspace;                                                                               
1937     }                                                                                                    
1938                                                                                                          
1939     public Hotseat getHotseat() {                                                                        
1940         return mHotseat;                                                                                 
1941     }                                                                                                    
1942                                                                                                          
1943     public ViewGroup getOverviewPanel() {                                                                
1944         return mOverviewPanel;                                                                           
1945     }                                                                                                    
1946                                                                                                          
1947     public SearchDropTargetBar getSearchBar() {                                                          
1948         return mSearchDropTargetBar;                                                                     
1949     }                                                                                                    
1950                                                                                                          
1951     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1952         return mAppWidgetHost;                                                                           
1953     }                                                                                                    
1954                                                                                                          
1955     public LauncherModel getModel() {                                                                    
1956         return mModel;                                                                                   
1957     }                                                                                                    
1958                                                                                                          
1959     protected SharedPreferences getSharedPrefs() {                                                       
1960         return mSharedPrefs;                                                                             
1961     }                                                                                                    
1962                                                                                                          
1963     public void closeSystemDialogs() {                                                                   
1964         getWindow().closeAllPanels();                                                                    
1965                                                                                                          
1966         // Whatever we were doing is hereby canceled.                                                    
1967         setWaitingForResult(false);                                                                      
1968     }                                                                                                    
1969                                                                                                          
1970     @Override                                                                                            
1971     protected void onNewIntent(Intent intent) {                                                          
1972         long startTime = 0;                                                                              
1973         if (DEBUG_RESUME_TIME) {                                                                         
1974             startTime = System.currentTimeMillis();                                                      
1975         }                                                                                                
1976         super.onNewIntent(intent);                                                                       
1977                                                                                                          
1978         // Close the menu                                                                                
1979         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1980             // also will cancel mWaitingForResult.                                                       
1981             closeSystemDialogs();                                                                        
1982                                                                                                          
1983             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1984                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1985                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1986                                                                                                          
1987             if (mWorkspace == null) {                                                                    
1988                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1989                 return;                                                                                  
1990             }                                                                                            
1991             Folder openFolder = mWorkspace.getOpenFolder();                                              
1992             // In all these cases, only animate if we're already on home                                 
1993             mWorkspace.exitWidgetResizeMode();                                                           
1994             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1995                     openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                     
1996                 mWorkspace.moveToDefaultScreen(true);                                                    
1997             }                                                                                            
1998                                                                                                          
1999             closeFolder();                                                                               
2000             exitSpringLoadedDragMode();                                                                  
2001                                                                                                          
2002             // If we are already on home, then just animate back to the workspace,                       
2003             // otherwise, just wait until onResume to set the state back to Workspace                    
2004             if (alreadyOnHome) {                                                                         
2005                 showWorkspace(true);                                                                     
2006             } else {                                                                                     
2007                 mOnResumeState = State.WORKSPACE;                                                        
2008             }                                                                                            
2009                                                                                                          
2010             final View v = getWindow().peekDecorView();                                                  
2011             if (v != null && v.getWindowToken() != null) {                                               
2012                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
2013                         INPUT_METHOD_SERVICE);                                                           
2014                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
2015             }                                                                                            
2016                                                                                                          
2017             // Reset the apps customize page                                                             
2018             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
2019                 mAppsCustomizeTabHost.reset();                                                           
2020             }                                                                                            
2021                                                                                                          
2022             onHomeIntent();                                                                              
2023         }                                                                                                
2024                                                                                                          
2025         if (DEBUG_RESUME_TIME) {                                                                         
2026             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
2027         }                                                                                                
2028     }                                                                                                    
2029                                                                                                          
2030     /**                                                                                                  
2031      * Override point for subclasses to prevent movement to the default screen when the home             
2032      * button is pressed. Used (for example) in GEL, to prevent movement during a search.                
2033      */                                                                                                  
2034     protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                          
2035         return true;                                                                                     
2036     }                                                                                                    
2037                                                                                                          
2038     /**                                                                                                  
2039      * Override point for subclasses to provide custom behaviour for when a home intent is fired.        
2040      */                                                                                                  
2041     protected void onHomeIntent() {                                                                      
2042         // Do nothing                                                                                    
2043     }                                                                                                    
2044                                                                                                          
2045     @Override                                                                                            
2046     public void onRestoreInstanceState(Bundle state) {                                                   
2047         super.onRestoreInstanceState(state);                                                             
2048         for (int page: mSynchronouslyBoundPages) {                                                       
2049             mWorkspace.restoreInstanceStateForChild(page);                                               
2050         }                                                                                                
2051     }                                                                                                    
2052                                                                                                          
2053     @Override                                                                                            
2054     protected void onSaveInstanceState(Bundle outState) {                                                
2055         if (mWorkspace.getChildCount() > 0) {                                                            
2056             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
2057                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
2058         }                                                                                                
2059         super.onSaveInstanceState(outState);                                                             
2060                                                                                                          
2061         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
2062         // We close any open folder since it will not be re-opened, and we need to make sure             
2063         // this state is reflected.                                                                      
2064         closeFolder();                                                                                   
2065                                                                                                          
2066         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
2067                 mWaitingForResult) {                                                                     
2068             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
2069             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
2070             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
2071             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
2072             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
2073             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
2074             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
2075             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
2076         }                                                                                                
2077                                                                                                          
2078         if (mFolderInfo != null && mWaitingForResult) {                                                  
2079             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
2080             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
2081         }                                                                                                
2082                                                                                                          
2083         // Save the current AppsCustomize tab                                                            
2084         if (mAppsCustomizeTabHost != null) {                                                             
2085             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
2086             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
2087             if (currentTabTag != null) {                                                                 
2088                 outState.putString("apps_customize_currentTab", currentTabTag);                          
2089             }                                                                                            
2090             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
2091             outState.putInt("apps_customize_currentIndex", currentIndex);                                
2092         }                                                                                                
2093         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2094     }                                                                                                    
2095                                                                                                          
2096     @Override                                                                                            
2097     public void onDestroy() {                                                                            
2098         super.onDestroy();                                                                               
2099                                                                                                          
2100         // Remove all pending runnables                                                                  
2101         mHandler.removeMessages(ADVANCE_MSG);                                                            
2102         mHandler.removeMessages(0);                                                                      
2103         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2104                                                                                                          
2105         // Stop callbacks from LauncherModel                                                             
2106         LauncherAppState app = (LauncherAppState.getInstance());                                         
2107                                                                                                          
2108         // It's possible to receive onDestroy after a new Launcher activity has                          
2109         // been created. In this case, don't interfere with the new Launcher.                            
2110         if (mModel.isCurrentCallbacks(this)) {                                                           
2111             mModel.stopLoader();                                                                         
2112             app.setLauncher(null);                                                                       
2113         }                                                                                                
2114                                                                                                          
2115         try {                                                                                            
2116             mAppWidgetHost.stopListening();                                                              
2117         } catch (NullPointerException ex) {                                                              
2118             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2119         }                                                                                                
2120         mAppWidgetHost = null;                                                                           
2121                                                                                                          
2122         mWidgetsToAdvance.clear();                                                                       
2123                                                                                                          
2124         TextKeyListener.getInstance().release();                                                         
2125                                                                                                          
2126         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2127         // to prevent leaking Launcher activities on orientation change.                                 
2128         if (mModel != null) {                                                                            
2129             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2130         }                                                                                                
2131                                                                                                          
2132         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2133         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2134                                                                                                          
2135         mDragLayer.clearAllResizeFrames();                                                               
2136         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2137         mWorkspace.removeAllWorkspaceScreens();                                                          
2138         mWorkspace = null;                                                                               
2139         mDragController = null;                                                                          
2140                                                                                                          
2141         PackageInstallerCompat.getInstance(this).onStop();                                               
2142         LauncherAnimUtils.onDestroyActivity();                                                           
2143     }                                                                                                    
2144                                                                                                          
2145     public DragController getDragController() {                                                          
2146         return mDragController;                                                                          
2147     }                                                                                                    
2148                                                                                                          
2149     @Override                                                                                            
2150     public void startActivityForResult(Intent intent, int requestCode) {                                 
2151         if (requestCode >= 0) {                                                                          
2152             setWaitingForResult(true);                                                                   
2153         }                                                                                                
2154         super.startActivityForResult(intent, requestCode);                                               
2155     }                                                                                                    
2156                                                                                                          
2157     /**                                                                                                  
2158      * Indicates that we want global search for this activity by setting the globalSearch                
2159      * argument for {@link #startSearch} to true.                                                        
2160      */                                                                                                  
2161     @Override                                                                                            
2162     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2163             Bundle appSearchData, boolean globalSearch) {                                                
2164                                                                                                          
2165         showWorkspace(true);                                                                             
2166                                                                                                          
2167         if (initialQuery == null) {                                                                      
2168             // Use any text typed in the launcher as the initial query                                   
2169             initialQuery = getTypedText();                                                               
2170         }                                                                                                
2171         if (appSearchData == null) {                                                                     
2172             appSearchData = new Bundle();                                                                
2173             appSearchData.putString("source", "launcher-search");                                        
2174         }                                                                                                
2175         Rect sourceBounds = new Rect();                                                                  
2176         if (mSearchDropTargetBar != null) {                                                              
2177             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2178         }                                                                                                
2179                                                                                                          
2180         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2181                 appSearchData, sourceBounds);                                                            
2182         if (clearTextImmediately) {                                                                      
2183             clearTypedText();                                                                            
2184         }                                                                                                
2185     }                                                                                                    
2186                                                                                                          
2187     /**                                                                                                  
2188      * Start a text search.                                                                              
2189      *                                                                                                   
2190      * @return {@code true} if the search will start immediately, so any further keypresses              
2191      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2192      * to buffer keypresses.                                                                             
2193      */                                                                                                  
2194     public boolean startSearch(String initialQuery,                                                      
2195             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2196         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2197                 appSearchData, sourceBounds);                                                            
2198         return false;                                                                                    
2199     }                                                                                                    
2200                                                                                                          
2201     /**                                                                                                  
2202      * Starts the global search activity. This code is a copied from SearchManager                       
2203      */                                                                                                  
2204     private void startGlobalSearch(String initialQuery,                                                  
2205             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2206         final SearchManager searchManager =                                                              
2207             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2208         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2209         if (globalSearchActivity == null) {                                                              
2210             Log.w(TAG, "No global search activity found.");                                              
2211             return;                                                                                      
2212         }                                                                                                
2213         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2214         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2215         intent.setComponent(globalSearchActivity);                                                       
2216         // Make sure that we have a Bundle to put source in                                              
2217         if (appSearchData == null) {                                                                     
2218             appSearchData = new Bundle();                                                                
2219         } else {                                                                                         
2220             appSearchData = new Bundle(appSearchData);                                                   
2221         }                                                                                                
2222         // Set source to package name of app that starts global search, if not set already.              
2223         if (!appSearchData.containsKey("source")) {                                                      
2224             appSearchData.putString("source", getPackageName());                                         
2225         }                                                                                                
2226         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2227         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2228             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2229         }                                                                                                
2230         if (selectInitialQuery) {                                                                        
2231             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2232         }                                                                                                
2233         intent.setSourceBounds(sourceBounds);                                                            
2234         try {                                                                                            
2235             startActivity(intent);                                                                       
2236         } catch (ActivityNotFoundException ex) {                                                         
2237             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2238         }                                                                                                
2239     }                                                                                                    
2240                                                                                                          
2241     public boolean isOnCustomContent() {                                                                 
2242         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2243     }                                                                                                    
2244                                                                                                          
2245     @Override                                                                                            
2246     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2247         super.onPrepareOptionsMenu(menu);                                                                
2248         if (!isOnCustomContent()) {                                                                      
2249             // Close any open folders                                                                    
2250             closeFolder();                                                                               
2251             // Stop resizing any widgets                                                                 
2252             mWorkspace.exitWidgetResizeMode();                                                           
2253             if (!mWorkspace.isInOverviewMode()) {                                                        
2254                 // Show the overview mode                                                                
2255                 showOverviewMode(true);                                                                  
2256             } else {                                                                                     
2257                 showWorkspace(true);                                                                     
2258             }                                                                                            
2259         }                                                                                                
2260         return false;                                                                                    
2261     }                                                                                                    
2262                                                                                                          
2263     @Override                                                                                            
2264     public boolean onSearchRequested() {                                                                 
2265         startSearch(null, false, null, true);                                                            
2266         // Use a custom animation for launching search                                                   
2267         return true;                                                                                     
2268     }                                                                                                    
2269                                                                                                          
2270     public boolean isWorkspaceLocked() {                                                                 
2271         return mWorkspaceLoading || mWaitingForResult;                                                   
2272     }                                                                                                    
2273                                                                                                          
2274     public boolean isWorkspaceLoading() {                                                                
2275         return mWorkspaceLoading;                                                                        
2276     }                                                                                                    
2277                                                                                                          
2278     private void setWorkspaceLoading(boolean value) {                                                    
2279         boolean isLocked = isWorkspaceLocked();                                                          
2280         mWorkspaceLoading = value;                                                                       
2281         if (isLocked != isWorkspaceLocked()) {                                                           
2282             onWorkspaceLockedChanged();                                                                  
2283         }                                                                                                
2284     }                                                                                                    
2285                                                                                                          
2286     private void setWaitingForResult(boolean value) {                                                    
2287         boolean isLocked = isWorkspaceLocked();                                                          
2288         mWaitingForResult = value;                                                                       
2289         if (isLocked != isWorkspaceLocked()) {                                                           
2290             onWorkspaceLockedChanged();                                                                  
2291         }                                                                                                
2292     }                                                                                                    
2293                                                                                                          
2294     protected void onWorkspaceLockedChanged() { }                                                        
2295                                                                                                          
2296     private void resetAddInfo() {                                                                        
2297         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2298         mPendingAddInfo.screenId = -1;                                                                   
2299         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2300         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2301         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2302         mPendingAddInfo.dropPos = null;                                                                  
2303     }                                                                                                    
2304                                                                                                          
2305     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2306             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2307         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2308     }                                                                                                    
2309                                                                                                          
2310     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2311             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int          
2312             delay) {                                                                                     
2313         if (appWidgetInfo.configure != null) {                                                           
2314             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2315             mPendingAddWidgetId = appWidgetId;                                                           
2316                                                                                                          
2317             // Launch over to configure widget, if needed                                                
2318             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2319                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2320                                                                                                          
2321         } else {                                                                                         
2322             // Otherwise just add it                                                                     
2323             Runnable onComplete = new Runnable() {                                                       
2324                 @Override                                                                                
2325                 public void run() {                                                                      
2326                     // Exit spring loaded mode if necessary after adding the widget                      
2327                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2328                             null);                                                                       
2329                 }                                                                                        
2330             };                                                                                           
2331             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2332                     appWidgetInfo);                                                                      
2333             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2334         }                                                                                                
2335     }                                                                                                    
2336                                                                                                          
2337     protected void moveToCustomContentScreen(boolean animate) {                                          
2338         // Close any folders that may be open.                                                           
2339         closeFolder();                                                                                   
2340         mWorkspace.moveToCustomContentScreen(animate);                                                   
2341     }                                                                                                    
2342                                                                                                          
2343     /**                                                                                                  
2344      * Process a shortcut drop.                                                                          
2345      *                                                                                                   
2346      * @param componentName The name of the component                                                    
2347      * @param screenId The ID of the screen where it should be added                                     
2348      * @param cell The cell it should be added to, optional                                              
2349      * @param position The location on the screen where it was dropped, optional                         
2350      */                                                                                                  
2351     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2352             int[] cell, int[] loc) {                                                                     
2353         resetAddInfo();                                                                                  
2354         mPendingAddInfo.container = container;                                                           
2355         mPendingAddInfo.screenId = screenId;                                                             
2356         mPendingAddInfo.dropPos = loc;                                                                   
2357                                                                                                          
2358         if (cell != null) {                                                                              
2359             mPendingAddInfo.cellX = cell[0];                                                             
2360             mPendingAddInfo.cellY = cell[1];                                                             
2361         }                                                                                                
2362                                                                                                          
2363         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2364         createShortcutIntent.setComponent(componentName);                                                
2365         processShortcut(createShortcutIntent);                                                           
2366     }                                                                                                    
2367                                                                                                          
2368     /**                                                                                                  
2369      * Process a widget drop.                                                                            
2370      *                                                                                                   
2371      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2372      * @param screenId The ID of the screen where it should be added                                     
2373      * @param cell The cell it should be added to, optional                                              
2374      * @param position The location on the screen where it was dropped, optional                         
2375      */                                                                                                  
2376     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                  
2377             int[] cell, int[] span, int[] loc) {                                                         
2378         resetAddInfo();                                                                                  
2379         mPendingAddInfo.container = info.container = container;                                          
2380         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2381         mPendingAddInfo.dropPos = loc;                                                                   
2382         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2383         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2384                                                                                                          
2385         if (cell != null) {                                                                              
2386             mPendingAddInfo.cellX = cell[0];                                                             
2387             mPendingAddInfo.cellY = cell[1];                                                             
2388         }                                                                                                
2389         if (span != null) {                                                                              
2390             mPendingAddInfo.spanX = span[0];                                                             
2391             mPendingAddInfo.spanY = span[1];                                                             
2392         }                                                                                                
2393                                                                                                          
2394         AppWidgetHostView hostView = info.boundWidget;                                                   
2395         int appWidgetId;                                                                                 
2396         if (hostView != null) {                                                                          
2397             appWidgetId = hostView.getAppWidgetId();                                                     
2398             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2399         } else {                                                                                         
2400             // In this case, we either need to start an activity to get permission to bind               
2401             // the widget, or we need to start an activity to configure the widget, or both.             
2402             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2403             Bundle options = info.bindOptions;                                                           
2404                                                                                                          
2405             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2406                     appWidgetId, info.info, options);                                                    
2407             if (success) {                                                                               
2408                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2409             } else {                                                                                     
2410                 mPendingAddWidgetInfo = info.info;                                                       
2411                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2412                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2413                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2414                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2415                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2416                 // TODO: we need to make sure that this accounts for the options bundle.                 
2417                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2418                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2419             }                                                                                            
2420         }                                                                                                
2421     }                                                                                                    
2422                                                                                                          
2423     void processShortcut(Intent intent) {                                                                
2424         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2425     }                                                                                                    
2426                                                                                                          
2427     void processWallpaper(Intent intent) {                                                               
2428         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2429     }                                                                                                    
2430                                                                                                          
2431     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2432             int cellY) {                                                                                 
2433         final FolderInfo folderInfo = new FolderInfo();                                                  
2434         folderInfo.title = getText(R.string.folder_name);                                                
2435                                                                                                          
2436         // Update the model                                                                              
2437         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2438                 false);                                                                                  
2439         sFolders.put(folderInfo.id, folderInfo);                                                         
2440                                                                                                          
2441         // Create the view                                                                               
2442         FolderIcon newFolder =                                                                           
2443             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2444         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2445                 isWorkspaceLocked());                                                                    
2446         // Force measure the new folder icon                                                             
2447         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2448         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2449         return newFolder;                                                                                
2450     }                                                                                                    
2451                                                                                                          
2452     void removeFolder(FolderInfo folder) {                                                               
2453         sFolders.remove(folder.id);                                                                      
2454     }                                                                                                    
2455                                                                                                          
2456     protected ComponentName getWallpaperPickerComponent() {                                              
2457         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2458     }                                                                                                    
2459                                                                                                          
2460     /**                                                                                                  
2461      * Registers various content observers. The current implementation registers                         
2462      * only a favorites observer to keep track of the favorites applications.                            
2463      */                                                                                                  
2464     private void registerContentObservers() {                                                            
2465         ContentResolver resolver = getContentResolver();                                                 
2466         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2467                 true, mWidgetObserver);                                                                  
2468     }                                                                                                    
2469                                                                                                          
2470     @Override                                                                                            
2471     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2472         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2473             switch (event.getKeyCode()) {                                                                
2474                 case KeyEvent.KEYCODE_HOME:                                                              
2475                     return true;                                                                         
2476                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2477                     if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                        
2478                         dumpState();                                                                     
2479                         return true;                                                                     
2480                     }                                                                                    
2481                     break;                                                                               
2482             }                                                                                            
2483         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2484             switch (event.getKeyCode()) {                                                                
2485                 case KeyEvent.KEYCODE_HOME:                                                              
2486                     return true;                                                                         
2487             }                                                                                            
2488         }                                                                                                
2489                                                                                                          
2490         return super.dispatchKeyEvent(event);                                                            
2491     }                                                                                                    
2492                                                                                                          
2493     @Override                                                                                            
2494     public void onBackPressed() {                                                                        
2495         if (isAllAppsVisible()) {                                                                        
2496             if (mAppsCustomizeContent.getContentType() ==                                                
2497                     AppsCustomizePagedView.ContentType.Applications) {                                   
2498                 showWorkspace(true);                                                                     
2499             } else {                                                                                     
2500                 showOverviewMode(true);                                                                  
2501             }                                                                                            
2502         } else if (mWorkspace.isInOverviewMode()) {                                                      
2503             mWorkspace.exitOverviewMode(true);                                                           
2504         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2505             Folder openFolder = mWorkspace.getOpenFolder();                                              
2506             if (openFolder.isEditingName()) {                                                            
2507                 openFolder.dismissEditingName();                                                         
2508             } else {                                                                                     
2509                 closeFolder();                                                                           
2510             }                                                                                            
2511         } else {                                                                                         
2512             mWorkspace.exitWidgetResizeMode();                                                           
2513                                                                                                          
2514             // Back button is a no-op here, but give at least some feedback for the button press         
2515             mWorkspace.showOutlinesTemporarily();                                                        
2516         }                                                                                                
2517     }                                                                                                    
2518                                                                                                          
2519     /**                                                                                                  
2520      * Re-listen when widgets are reset.                                                                 
2521      */                                                                                                  
2522     private void onAppWidgetReset() {                                                                    
2523         if (mAppWidgetHost != null) {                                                                    
2524             mAppWidgetHost.startListening();                                                             
2525         }                                                                                                
2526     }                                                                                                    
2527                                                                                                          
2528     /**                                                                                                  
2529      * Launches the intent referred by the clicked shortcut.                                             
2530      *                                                                                                   
2531      * @param v The view representing the clicked shortcut.                                              
2532      */                                                                                                  
2533     public void onClick(View v) {                                                                        
2534         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2535         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2536         if (v.getWindowToken() == null) {                                                                
2537             return;                                                                                      
2538         }                                                                                                
2539                                                                                                          
2540         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2541             return;                                                                                      
2542         }                                                                                                
2543                                                                                                          
2544         if (v instanceof Workspace) {                                                                    
2545             if (mWorkspace.isInOverviewMode()) {                                                         
2546                 mWorkspace.exitOverviewMode(true);                                                       
2547             }                                                                                            
2548             return;                                                                                      
2549         }                                                                                                
2550                                                                                                          
2551         if (v instanceof CellLayout) {                                                                   
2552             if (mWorkspace.isInOverviewMode()) {                                                         
2553                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2554             }                                                                                            
2555         }                                                                                                
2556                                                                                                          
2557         Object tag = v.getTag();                                                                         
2558         if (tag instanceof ShortcutInfo) {                                                               
2559             onClickAppShortcut(v);                                                                       
2560         } else if (tag instanceof FolderInfo) {                                                          
2561             if (v instanceof FolderIcon) {                                                               
2562                 onClickFolderIcon(v);                                                                    
2563             }                                                                                            
2564         } else if (v == mAllAppsButton) {                                                                
2565             onClickAllAppsButton(v);                                                                     
2566         } else if (tag instanceof AppInfo) {                                                             
2567             startAppShortcutOrInfoActivity(v);                                                           
2568         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2569             if (v instanceof PendingAppWidgetHostView) {                                                 
2570                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2571             }                                                                                            
2572         }                                                                                                
2573     }                                                                                                    
2574                                                                                                          
2575     public void onClickPagedViewIcon(View v) {                                                           
2576         startAppShortcutOrInfoActivity(v);                                                               
2577     }                                                                                                    
2578                                                                                                          
2579     public boolean onTouch(View v, MotionEvent event) {                                                  
2580         return false;                                                                                    
2581     }                                                                                                    
2582                                                                                                          
2583     /**                                                                                                  
2584      * Event handler for the app widget view which has not fully restored.                               
2585      */                                                                                                  
2586     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2587         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2588         if (v.isReadyForClickSetup()) {                                                                  
2589             int widgetId = info.appWidgetId;                                                             
2590             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2591             if (appWidgetInfo != null) {                                                                 
2592                 mPendingAddWidgetInfo = appWidgetInfo;                                                   
2593                 mPendingAddInfo.copyFrom(info);                                                          
2594                 mPendingAddWidgetId = widgetId;                                                          
2595                                                                                                          
2596                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2597                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2598             }                                                                                            
2599         } else if (info.installProgress < 0) {                                                           
2600             // The install has not been queued                                                           
2601             final String packageName = info.providerName.getPackageName();                               
2602             showBrokenAppInstallDialog(packageName,                                                      
2603                 new DialogInterface.OnClickListener() {                                                  
2604                     public void onClick(DialogInterface dialog, int id) {                                
2605                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2606                     }                                                                                    
2607                 });                                                                                      
2608         } else {                                                                                         
2609             // Download has started.                                                                     
2610             final String packageName = info.providerName.getPackageName();                               
2611             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2612         }                                                                                                
2613     }                                                                                                    
2614                                                                                                          
2615     /**                                                                                                  
2616      * Event handler for the search button                                                               
2617      *                                                                                                   
2618      * @param v The view that was clicked.                                                               
2619      */                                                                                                  
2620     public void onClickSearchButton(View v) {                                                            
2621         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2622                                                                                                          
2623         onSearchRequested();                                                                             
2624     }                                                                                                    
2625                                                                                                          
2626     /**                                                                                                  
2627      * Event handler for the voice button                                                                
2628      *                                                                                                   
2629      * @param v The view that was clicked.                                                               
2630      */                                                                                                  
2631     public void onClickVoiceButton(View v) {                                                             
2632         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2633                                                                                                          
2634         startVoice();                                                                                    
2635     }                                                                                                    
2636                                                                                                          
2637     public void startVoice() {                                                                           
2638         try {                                                                                            
2639             final SearchManager searchManager =                                                          
2640                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);                            
2641             ComponentName activityName = searchManager.getGlobalSearchActivity();                        
2642             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2643             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2644             if (activityName != null) {                                                                  
2645                 intent.setPackage(activityName.getPackageName());                                        
2646             }                                                                                            
2647             startActivity(null, intent, "onClickVoiceButton");                                           
2648         } catch (ActivityNotFoundException e) {                                                          
2649             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2650             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2651             startActivitySafely(null, intent, "onClickVoiceButton");                                     
2652         }                                                                                                
2653     }                                                                                                    
2654                                                                                                          
2655     /**                                                                                                  
2656      * Event handler for the "grid" button that appears on the home screen, which                        
2657      * enters all apps mode.                                                                             
2658      *                                                                                                   
2659      * @param v The view that was clicked.                                                               
2660      */                                                                                                  
2661     protected void onClickAllAppsButton(View v) {                                                        
2662         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2663         if (isAllAppsVisible()) {                                                                        
2664             showWorkspace(true);                                                                         
2665         } else {                                                                                         
2666             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                   
2667         }                                                                                                
2668     }                                                                                                    
2669                                                                                                          
2670     private void showBrokenAppInstallDialog(final String packageName, DialogInterface.OnClickListener onS🔵
2671         new AlertDialog.Builder(this).setTitle(R.string.abandoned_promises_title).setMessage(R.string.aba🔵
2672             public void onClick(DialogInterface dialog, int id) {                                        
2673                 final UserHandleCompat user = UserHandleCompat.myUserHandle();                           
2674                 mWorkspace.removeAbandonedPromise(packageName, user);                                    
2675             }                                                                                            
2676         }).create().show();                                                                              
2677         return;                                                                                          
2678     }                                                                                                    
2679                                                                                                          
2680     /**                                                                                                  
2681      * Event handler for an app shortcut click.                                                          
2682      *                                                                                                   
2683      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2684      */                                                                                                  
2685     protected void onClickAppShortcut(final View v) {                                                    
2686         if (LOGD) {                                                                                      
2687             Log.d(TAG, "onClickAppShortcut");                                                            
2688         }                                                                                                
2689         Object tag = v.getTag();                                                                         
2690         if (!(tag instanceof ShortcutInfo)) {                                                            
2691             throw new IllegalArgumentException("Input must be a Shortcut");                              
2692         }                                                                                                
2693         // Open shortcut                                                                                 
2694         final ShortcutInfo shortcut = ((ShortcutInfo) (tag));                                            
2695         if (shortcut.isDisabled != 0) {                                                                  
2696             int error = R.string.activity_not_available;                                                 
2697             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2698                 error = R.string.safemode_shortcut_error;                                                
2699             }                                                                                            
2700             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2701             return;                                                                                      
2702         }                                                                                                
2703         final Intent intent = shortcut.intent;                                                           
2704         // Check for special shortcuts                                                                   
2705         if (intent.getComponent() != null) {                                                             
2706             final String shortcutClass = intent.getComponent().getClassName();                           
2707             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2708                 MemoryDumpActivity.startDump(this);                                                      
2709                 return;                                                                                  
2710             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2711                 toggleShowWeightWatcher();                                                               
2712                 return;                                                                                  
2713             }                                                                                            
2714         }                                                                                                
2715         // Check for abandoned promise                                                                   
2716         if (((v instanceof BubbleTextView) && shortcut.isPromise()) && (!shortcut.hasStatusFlag(ShortcutI🔵
2717             showBrokenAppInstallDialog(shortcut.getTargetComponent().getPackageName(), new DialogInterfac🔵
2718                 public void onClick(DialogInterface dialog, int id) {                                    
2719                     startAppShortcutOrInfoActivity(v);                                                   
2720                 }                                                                                        
2721             });                                                                                          
2722             return;                                                                                      
2723         }                                                                                                
2724         // Start activities                                                                              
2725         startAppShortcutOrInfoActivity(v);                                                               
2726     }                                                                                                    
2727                                                                                                          
2728     private void startAppShortcutOrInfoActivity(View v) {                                                
2729         Object tag = v.getTag();                                                                         
2730         final ShortcutInfo shortcut;                                                                     
2731         final Intent intent;                                                                             
2732         if (tag instanceof ShortcutInfo) {                                                               
2733             shortcut = (ShortcutInfo) tag;                                                               
2734             intent = shortcut.intent;                                                                    
2735             int[] pos = new int[2];                                                                      
2736             v.getLocationOnScreen(pos);                                                                  
2737             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2738                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2739                                                                                                          
2740         } else if (tag instanceof AppInfo) {                                                             
2741             shortcut = null;                                                                             
2742             intent = ((AppInfo) tag).intent;                                                             
2743         } else {                                                                                         
2744             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2745         }                                                                                                
2746                                                                                                          
2747         boolean success = startActivitySafely(v, intent, tag);                                           
2748         mStats.recordLaunch(intent, shortcut);                                                           
2749                                                                                                          
2750         if (success && v instanceof BubbleTextView) {                                                    
2751             mWaitingForResume = (BubbleTextView) v;                                                      
2752             mWaitingForResume.setStayPressed(true);                                                      
2753         }                                                                                                
2754     }                                                                                                    
2755                                                                                                          
2756     /**                                                                                                  
2757      * Event handler for a folder icon click.                                                            
2758      *                                                                                                   
2759      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2760      */                                                                                                  
2761     protected void onClickFolderIcon(View v) {                                                           
2762         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2763         if (!(v instanceof FolderIcon)){                                                                 
2764             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2765         }                                                                                                
2766                                                                                                          
2767         FolderIcon folderIcon = (FolderIcon) v;                                                          
2768         final FolderInfo info = folderIcon.getFolderInfo();                                              
2769         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2770                                                                                                          
2771         // If the folder info reports that the associated folder is open, then verify that               
2772         // it is actually opened. There have been a few instances where this gets out of sync.           
2773         if (info.opened && openFolder == null) {                                                         
2774             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2775                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2776             info.opened = false;                                                                         
2777         }                                                                                                
2778                                                                                                          
2779         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2780             // Close any open folder                                                                     
2781             closeFolder();                                                                               
2782             // Open the requested folder                                                                 
2783             openFolder(folderIcon);                                                                      
2784         } else {                                                                                         
2785             // Find the open folder...                                                                   
2786             int folderScreen;                                                                            
2787             if (openFolder != null) {                                                                    
2788                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2789                 // .. and close it                                                                       
2790                 closeFolder(openFolder);                                                                 
2791                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2792                     // Close any folder open on the current screen                                       
2793                     closeFolder();                                                                       
2794                     // Pull the folder onto this screen                                                  
2795                     openFolder(folderIcon);                                                              
2796                 }                                                                                        
2797             }                                                                                            
2798         }                                                                                                
2799     }                                                                                                    
2800                                                                                                          
2801     /**                                                                                                  
2802      * Event handler for the (Add) Widgets button that appears after a long press                        
2803      * on the home screen.                                                                               
2804      */                                                                                                  
2805     protected void onClickAddWidgetButton(View view) {                                                   
2806         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2807         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                             
2808     }                                                                                                    
2809                                                                                                          
2810     /**                                                                                                  
2811      * Event handler for the wallpaper picker button that appears after a long press                     
2812      * on the home screen.                                                                               
2813      */                                                                                                  
2814     protected void onClickWallpaperPicker(View v) {                                                      
2815         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2816         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2817         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2818         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2819     }                                                                                                    
2820                                                                                                          
2821     /**                                                                                                  
2822      * Event handler for a click on the settings button that appears after a long press                  
2823      * on the home screen.                                                                               
2824      */                                                                                                  
2825     protected void onClickSettingsButton(View v) {                                                       
2826         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2827     }                                                                                                    
2828                                                                                                          
2829     public void onTouchDownAllAppsButton(View v) {                                                       
2830         // Provide the same haptic feedback that the system offers for virtual keys.                     
2831         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2832     }                                                                                                    
2833                                                                                                          
2834     public void performHapticFeedbackOnTouchDown(View v) {                                               
2835         // Provide the same haptic feedback that the system offers for virtual keys.                     
2836         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2837     }                                                                                                    
2838                                                                                                          
2839     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2840         if (mHapticFeedbackTouchListener == null) {                                                      
2841             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2842                 @Override                                                                                
2843                 public boolean onTouch(View v, MotionEvent event) {                                      
2844                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2845                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2846                     }                                                                                    
2847                     return false;                                                                        
2848                 }                                                                                        
2849             };                                                                                           
2850         }                                                                                                
2851         return mHapticFeedbackTouchListener;                                                             
2852     }                                                                                                    
2853                                                                                                          
2854     public void onDragStarted(View view) {}                                                              
2855                                                                                                          
2856     /**                                                                                                  
2857      * Called when the user stops interacting with the launcher.                                         
2858      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2859      */                                                                                                  
2860     protected void onInteractionEnd() {}                                                                 
2861                                                                                                          
2862     /**                                                                                                  
2863      * Called when the user starts interacting with the launcher.                                        
2864      * The possible interactions are:                                                                    
2865      *  - open all apps                                                                                  
2866      *  - reorder an app shortcut, or a widget                                                           
2867      *  - open the overview mode.                                                                        
2868      * This is a good time to stop doing things that only make sense                                     
2869      * when the user is on the homescreen and not doing housekeeping.                                    
2870      */                                                                                                  
2871     protected void onInteractionBegin() {}                                                               
2872                                                                                                          
2873     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2874         String packageName = componentName.getPackageName();                                             
2875         try {                                                                                            
2876             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2877             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2878             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2879         } catch (SecurityException e) {                                                                  
2880             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2881             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2882         } catch (ActivityNotFoundException e) {                                                          
2883             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2884             Log.e(TAG, "Unable to launch settings");                                                     
2885         }                                                                                                
2886     }                                                                                                    
2887                                                                                                          
2888     // returns true if the activity was started                                                          
2889     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2890             UserHandleCompat user) {                                                                     
2891         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2892             // System applications cannot be installed. For now, show a toast explaining that.           
2893             // We may give them the option of disabling apps this way.                                   
2894             int messageId = R.string.uninstall_system_app_text;                                          
2895             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2896             return false;                                                                                
2897         } else {                                                                                         
2898             String packageName = componentName.getPackageName();                                         
2899             String className = componentName.getClassName();                                             
2900             Intent intent = new Intent(                                                                  
2901                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2902             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2903                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2904             if (user != null) {                                                                          
2905                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2906             }                                                                                            
2907             startActivity(intent);                                                                       
2908             return true;                                                                                 
2909         }                                                                                                
2910     }                                                                                                    
2911                                                                                                          
2912     boolean startActivity(View v, Intent intent, Object tag) {                                           
2913         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2914         try {                                                                                            
2915             // Only launch using the new animation if the shortcut has not opted out (this is a          
2916             // private contract between launcher and may be ignored in the future).                      
2917             boolean useLaunchAnimation = (v != null) &&                                                  
2918                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2919             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2920             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2921                                                                                                          
2922             UserHandleCompat user = null;                                                                
2923             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2924                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2925                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2926             }                                                                                            
2927                                                                                                          
2928             Bundle optsBundle = null;                                                                    
2929             if (useLaunchAnimation) {                                                                    
2930                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2931                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2932                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2933                 optsBundle = opts.toBundle();                                                            
2934             }                                                                                            
2935                                                                                                          
2936             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2937                 // Could be launching some bookkeeping activity                                          
2938                 startActivity(intent, optsBundle);                                                       
2939             } else {                                                                                     
2940                 // TODO Component can be null when shortcuts are supported for secondary user            
2941                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2942                         intent.getSourceBounds(), optsBundle);                                           
2943             }                                                                                            
2944             return true;                                                                                 
2945         } catch (SecurityException e) {                                                                  
2946             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2947             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2948                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2949                     "or use the exported attribute for this activity. "                                  
2950                     + "tag="+ tag + " intent=" + intent, e);                                             
2951         }                                                                                                
2952         return false;                                                                                    
2953     }                                                                                                    
2954                                                                                                          
2955     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2956         boolean success = false;                                                                         
2957         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2958             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2959             return false;                                                                                
2960         }                                                                                                
2961         try {                                                                                            
2962             success = startActivity(v, intent, tag);                                                     
2963         } catch (ActivityNotFoundException e) {                                                          
2964             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2965             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2966         }                                                                                                
2967         return success;                                                                                  
2968     }                                                                                                    
2969                                                                                                          
2970     /**                                                                                                  
2971      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2972      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2973      */                                                                                                  
2974     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2975         final int width = fi.getMeasuredWidth();                                                         
2976         final int height = fi.getMeasuredHeight();                                                       
2977                                                                                                          
2978         // Lazy load ImageView, Bitmap and Canvas                                                        
2979         if (mFolderIconImageView == null) {                                                              
2980             mFolderIconImageView = new ImageView(this);                                                  
2981         }                                                                                                
2982         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2983                 mFolderIconBitmap.getHeight() != height) {                                               
2984             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2985             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2986         }                                                                                                
2987                                                                                                          
2988         DragLayer.LayoutParams lp;                                                                       
2989         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2990             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2991         } else {                                                                                         
2992             lp = new DragLayer.LayoutParams(width, height);                                              
2993         }                                                                                                
2994                                                                                                          
2995         // The layout from which the folder is being opened may be scaled, adjust the starting           
2996         // view size by this scale factor.                                                               
2997         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2998         lp.customPosition = true;                                                                        
2999         lp.x = mRectForFolderAnimation.left;                                                             
3000         lp.y = mRectForFolderAnimation.top;                                                              
3001         lp.width = (int) (scale * width);                                                                
3002         lp.height = (int) (scale * height);                                                              
3003                                                                                                          
3004         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3005         fi.draw(mFolderIconCanvas);                                                                      
3006         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3007         if (fi.getFolder() != null) {                                                                    
3008             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3009             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3010         }                                                                                                
3011         // Just in case this image view is still in the drag layer from a previous animation,            
3012         // we remove it and re-add it.                                                                   
3013         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3014             mDragLayer.removeView(mFolderIconImageView);                                                 
3015         }                                                                                                
3016         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3017         if (fi.getFolder() != null) {                                                                    
3018             fi.getFolder().bringToFront();                                                               
3019         }                                                                                                
3020     }                                                                                                    
3021                                                                                                          
3022     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3023         if (fi == null) return;                                                                          
3024         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3025         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3026         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3027                                                                                                          
3028         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3029         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3030             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3031             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3032             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3033         }                                                                                                
3034                                                                                                          
3035         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3036         copyFolderIconToImage(fi);                                                                       
3037         fi.setVisibility(View.INVISIBLE);                                                                
3038                                                                                                          
3039         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3040                 scaleX, scaleY);                                                                         
3041         if (Utilities.isLmpOrAbove()) {                                                                  
3042             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3043         }                                                                                                
3044         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3045         oa.start();                                                                                      
3046     }                                                                                                    
3047                                                                                                          
3048     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3049         if (fi == null) return;                                                                          
3050         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3051         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3052         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3053                                                                                                          
3054         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3055                                                                                                          
3056         // We remove and re-draw the FolderIcon in-case it has changed                                   
3057         mDragLayer.removeView(mFolderIconImageView);                                                     
3058         copyFolderIconToImage(fi);                                                                       
3059         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3060                 scaleX, scaleY);                                                                         
3061         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3062         oa.addListener(new AnimatorListenerAdapter() {                                                   
3063             @Override                                                                                    
3064             public void onAnimationEnd(Animator animation) {                                             
3065                 if (cl != null) {                                                                        
3066                     cl.clearFolderLeaveBehind();                                                         
3067                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3068                     mDragLayer.removeView(mFolderIconImageView);                                         
3069                     fi.setVisibility(View.VISIBLE);                                                      
3070                 }                                                                                        
3071             }                                                                                            
3072         });                                                                                              
3073         oa.start();                                                                                      
3074     }                                                                                                    
3075                                                                                                          
3076     /**                                                                                                  
3077      * Opens the user folder described by the specified tag. The opening of the folder                   
3078      * is animated relative to the specified View. If the View is null, no animation                     
3079      * is played.                                                                                        
3080      *                                                                                                   
3081      * @param folderInfo The FolderInfo describing the folder to open.                                   
3082      */                                                                                                  
3083     public void openFolder(FolderIcon folderIcon) {                                                      
3084         Folder folder = folderIcon.getFolder();                                                          
3085         FolderInfo info = folder.mInfo;                                                                  
3086                                                                                                          
3087         info.opened = true;                                                                              
3088                                                                                                          
3089         // Just verify that the folder hasn't already been added to the DragLayer.                       
3090         // There was a one-off crash where the folder had a parent already.                              
3091         if (folder.getParent() == null) {                                                                
3092             mDragLayer.addView(folder);                                                                  
3093             mDragController.addDropTarget((DropTarget) folder);                                          
3094         } else {                                                                                         
3095             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3096                     folder.getParent() + ").");                                                          
3097         }                                                                                                
3098         folder.animateOpen();                                                                            
3099         growAndFadeOutFolderIcon(folderIcon);                                                            
3100                                                                                                          
3101         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3102         // the workspace items                                                                           
3103         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3104         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3105     }                                                                                                    
3106                                                                                                          
3107     public void closeFolder() {                                                                          
3108         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3109         if (folder != null) {                                                                            
3110             if (folder.isEditingName()) {                                                                
3111                 folder.dismissEditingName();                                                             
3112             }                                                                                            
3113             closeFolder(folder);                                                                         
3114         }                                                                                                
3115     }                                                                                                    
3116                                                                                                          
3117     void closeFolder(Folder folder) {                                                                    
3118         folder.getInfo().opened = false;                                                                 
3119                                                                                                          
3120         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3121         if (parent != null) {                                                                            
3122             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3123             shrinkAndFadeInFolderIcon(fi);                                                               
3124         }                                                                                                
3125         folder.animateClosed();                                                                          
3126                                                                                                          
3127         // Notify the accessibility manager that this folder "window" has disappeard and no              
3128         // longer occludeds the workspace items                                                          
3129         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3130     }                                                                                                    
3131                                                                                                          
3132     public boolean onLongClick(View v) {                                                                 
3133         if (!isDraggingEnabled()) return false;                                                          
3134         if (isWorkspaceLocked()) return false;                                                           
3135         if (mState != State.WORKSPACE) return false;                                                     
3136                                                                                                          
3137         if (v instanceof Workspace) {                                                                    
3138             if (!mWorkspace.isInOverviewMode()) {                                                        
3139                 if (mWorkspace.enterOverviewMode()) {                                                    
3140                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3141                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3142                     return true;                                                                         
3143                 } else {                                                                                 
3144                     return false;                                                                        
3145                 }                                                                                        
3146             } else {                                                                                     
3147                 return false;                                                                            
3148             }                                                                                            
3149         }                                                                                                
3150                                                                                                          
3151         CellLayout.CellInfo longClickCellInfo = null;                                                    
3152         View itemUnderLongClick = null;                                                                  
3153         if (v.getTag() instanceof ItemInfo) {                                                            
3154             ItemInfo info = (ItemInfo) v.getTag();                                                       
3155             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3156             itemUnderLongClick = longClickCellInfo.cell;                                                 
3157             resetAddInfo();                                                                              
3158         }                                                                                                
3159                                                                                                          
3160         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3161         // on hotseat items.                                                                             
3162         final boolean inHotseat = isHotseatLayout(v);                                                    
3163         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3164         if (allowLongPress && !mDragController.isDragging()) {                                           
3165             if (itemUnderLongClick == null) {                                                            
3166                 // User long pressed on empty space                                                      
3167                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3168                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3169                 if (mWorkspace.isInOverviewMode()) {                                                     
3170                     mWorkspace.startReordering(v);                                                       
3171                 } else {                                                                                 
3172                     mWorkspace.enterOverviewMode();                                                      
3173                 }                                                                                        
3174             } else {                                                                                     
3175                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3176                         mHotseat.getOrderInHotseat(                                                      
3177                                 longClickCellInfo.cellX,                                                 
3178                                 longClickCellInfo.cellY));                                               
3179                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3180                     // User long pressed on an item                                                      
3181                     mWorkspace.startDrag(longClickCellInfo);                                             
3182                 }                                                                                        
3183             }                                                                                            
3184         }                                                                                                
3185         return true;                                                                                     
3186     }                                                                                                    
3187                                                                                                          
3188     boolean isHotseatLayout(View layout) {                                                               
3189         return mHotseat != null && layout != null &&                                                     
3190                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3191     }                                                                                                    
3192                                                                                                          
3193     /**                                                                                                  
3194      * Returns the CellLayout of the specified container at the specified screen.                        
3195      */                                                                                                  
3196     CellLayout getCellLayout(long container, long screenId) {                                            
3197         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3198             if (mHotseat != null) {                                                                      
3199                 return mHotseat.getLayout();                                                             
3200             } else {                                                                                     
3201                 return null;                                                                             
3202             }                                                                                            
3203         } else {                                                                                         
3204             return (CellLayout) mWorkspace.getScreenWithId(screenId);                                    
3205         }                                                                                                
3206     }                                                                                                    
3207                                                                                                          
3208     public boolean isAllAppsVisible() {                                                                  
3209         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);             
3210     }                                                                                                    
3211                                                                                                          
3212     private void setWorkspaceBackground(boolean workspace) {                                             
3213         mLauncherView.setBackground(workspace ?                                                          
3214                 mWorkspaceBackgroundDrawable : null);                                                    
3215     }                                                                                                    
3216                                                                                                          
3217     protected void changeWallpaperVisiblity(boolean visible) {                                           
3218         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3219         int curflags = getWindow().getAttributes().flags                                                 
3220                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3221         if (wpflags != curflags) {                                                                       
3222             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3223         }                                                                                                
3224         setWorkspaceBackground(visible);                                                                 
3225     }                                                                                                    
3226                                                                                                          
3227     private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {    
3228         if (v instanceof LauncherTransitionable) {                                                       
3229             ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);       
3230         }                                                                                                
3231     }                                                                                                    
3232                                                                                                          
3233     private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {      
3234         if (v instanceof LauncherTransitionable) {                                                       
3235             ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);         
3236         }                                                                                                
3237                                                                                                          
3238         // Update the workspace transition step as well                                                  
3239         dispatchOnLauncherTransitionStep(v, 0f);                                                         
3240     }                                                                                                    
3241                                                                                                          
3242     private void dispatchOnLauncherTransitionStep(View v, float t) {                                     
3243         if (v instanceof LauncherTransitionable) {                                                       
3244             ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                              
3245         }                                                                                                
3246     }                                                                                                    
3247                                                                                                          
3248     private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {        
3249         if (v instanceof LauncherTransitionable) {                                                       
3250             ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);           
3251         }                                                                                                
3252                                                                                                          
3253         // Update the workspace transition step as well                                                  
3254         dispatchOnLauncherTransitionStep(v, 1f);                                                         
3255     }                                                                                                    
3256                                                                                                          
3257     /**                                                                                                  
3258      * Things to test when changing the following seven functions.                                       
3259      *   - Home from workspace                                                                           
3260      *          - from center screen                                                                     
3261      *          - from other screens                                                                     
3262      *   - Home from all apps                                                                            
3263      *          - from center screen                                                                     
3264      *          - from other screens                                                                     
3265      *   - Back from all apps                                                                            
3266      *          - from center screen                                                                     
3267      *          - from other screens                                                                     
3268      *   - Launch app from workspace and quit                                                            
3269      *          - with back                                                                              
3270      *          - with home                                                                              
3271      *   - Launch app from all apps and quit                                                             
3272      *          - with back                                                                              
3273      *          - with home                                                                              
3274      *   - Go to a screen that's not the default, then all                                               
3275      *     apps, and launch and app, and go back                                                         
3276      *          - with back                                                                              
3277      *          -with home                                                                               
3278      *   - On workspace, long press power and go back                                                    
3279      *          - with back                                                                              
3280      *          - with home                                                                              
3281      *   - On all apps, long press power and go back                                                     
3282      *          - with back                                                                              
3283      *          - with home                                                                              
3284      *   - On workspace, power off                                                                       
3285      *   - On all apps, power off                                                                        
3286      *   - Launch an app and turn off the screen while in that app                                       
3287      *          - Go back with home key                                                                  
3288      *          - Go back with back key  TODO: make this not go to workspace                             
3289      *          - From all apps                                                                          
3290      *          - From workspace                                                                         
3291      *   - Enter and exit car mode (becuase it causes an extra configuration changed)                    
3292      *          - From all apps                                                                          
3293      *          - From the center workspace                                                              
3294      *          - From another workspace                                                                 
3295      */                                                                                                  
3296                                                                                                          
3297     /**                                                                                                  
3298      * Zoom the camera out from the workspace to reveal 'toView'.                                        
3299      * Assumes that the view to show is anchored at either the very top or very bottom                   
3300      * of the screen.                                                                                    
3301      */                                                                                                  
3302     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {           
3303         AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();         
3304         showAppsCustomizeHelper(animated, springLoaded, contentType);                                    
3305     }                                                                                                    
3306                                                                                                          
3307     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,             
3308                                          final AppsCustomizePagedView.ContentType contentType) {         
3309         if (mStateAnimation != null) {                                                                   
3310             mStateAnimation.setDuration(0);                                                              
3311             mStateAnimation.cancel();                                                                    
3312             mStateAnimation = null;                                                                      
3313         }                                                                                                
3314                                                                                                          
3315         boolean material = Utilities.isLmpOrAbove();                                                     
3316                                                                                                          
3317         final Resources res = getResources();                                                            
3318                                                                                                          
3319         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                   
3320         final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);               
3321         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);             
3322         final int itemsAlphaStagger =                                                                    
3323                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3324                                                                                                          
3325         final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);       
3326         final View fromView = mWorkspace;                                                                
3327         final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                       
3328                                                                                                          
3329         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3330                                                                                                          
3331         Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?     
3332                 Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                         
3333         Animator workspaceAnim =                                                                         
3334                 mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                
3335         if (!LauncherAppState.isDisableAllApps()                                                         
3336                 || contentType == AppsCustomizePagedView.ContentType.Widgets) {                          
3337             // Set the content type for the all apps/widgets space                                       
3338             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                  
3339         }                                                                                                
3340                                                                                                          
3341         // If for some reason our views aren't initialized, don't animate                                
3342         boolean initialized = getAllAppsButton() != null;                                                
3343                                                                                                          
3344         if (animated && initialized) {                                                                   
3345             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3346             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3347                     toView.findViewById(R.id.apps_customize_pane_content);                               
3348                                                                                                          
3349             final View page = content.getPageAt(content.getCurrentPage());                               
3350             final View revealView = toView.findViewById(R.id.fake_page);                                 
3351                                                                                                          
3352             final float initialPanelAlpha = 1f;                                                          
3353                                                                                                          
3354             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;      
3355             if (isWidgetTray) {                                                                          
3356                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                
3357             } else {                                                                                     
3358                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                     
3359             }                                                                                            
3360                                                                                                          
3361             // Hide the real page background, and swap in the fake one                                   
3362             content.setPageBackgroundsVisible(false);                                                    
3363             revealView.setVisibility(View.VISIBLE);                                                      
3364             // We need to hide this view as the animation start will be posted.                          
3365             revealView.setAlpha(0);                                                                      
3366                                                                                                          
3367             int width = revealView.getMeasuredWidth();                                                   
3368             int height = revealView.getMeasuredHeight();                                                 
3369             float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);         
3370                                                                                                          
3371             revealView.setTranslationY(0);                                                               
3372             revealView.setTranslationX(0);                                                               
3373                                                                                                          
3374             // Get the y delta between the center of the page and the center of the all apps button      
3375             int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                
3376                     getAllAppsButton(), null);                                                           
3377                                                                                                          
3378             float alpha = 0;                                                                             
3379             float xDrift = 0;                                                                            
3380             float yDrift = 0;                                                                            
3381             if (material) {                                                                              
3382                 alpha = isWidgetTray ? 0.3f : 1f;                                                        
3383                 yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                             
3384                 xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                      
3385             } else {                                                                                     
3386                 yDrift = 2 * height / 3;                                                                 
3387                 xDrift = 0;                                                                              
3388             }                                                                                            
3389             final float initAlpha = alpha;                                                               
3390                                                                                                          
3391             revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                     
3392             layerViews.add(revealView);                                                                  
3393             PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);      
3394             PropertyValuesHolder panelDriftY =                                                           
3395                     PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                             
3396             PropertyValuesHolder panelDriftX =                                                           
3397                     PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                             
3398                                                                                                          
3399             ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,        
3400                     panelAlpha, panelDriftY, panelDriftX);                                               
3401                                                                                                          
3402             panelAlphaAndDrift.setDuration(revealDuration);                                              
3403             panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                   
3404                                                                                                          
3405             mStateAnimation.play(panelAlphaAndDrift);                                                    
3406                                                                                                          
3407             if (page != null) {                                                                          
3408                 page.setVisibility(View.VISIBLE);                                                        
3409                 page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3410                 layerViews.add(page);                                                                    
3411                                                                                                          
3412                 ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);      
3413                 page.setTranslationY(yDrift);                                                            
3414                 pageDrift.setDuration(revealDuration);                                                   
3415                 pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                        
3416                 pageDrift.setStartDelay(itemsAlphaStagger);                                              
3417                 mStateAnimation.play(pageDrift);                                                         
3418                                                                                                          
3419                 page.setAlpha(0f);                                                                       
3420                 ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);               
3421                 itemsAlpha.setDuration(revealDuration);                                                  
3422                 itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                            
3423                 itemsAlpha.setStartDelay(itemsAlphaStagger);                                             
3424                 mStateAnimation.play(itemsAlpha);                                                        
3425             }                                                                                            
3426                                                                                                          
3427             View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);               
3428             pageIndicators.setAlpha(0.01f);                                                              
3429             ObjectAnimator indicatorsAlpha =                                                             
3430                     ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                 
3431             indicatorsAlpha.setDuration(revealDuration);                                                 
3432             mStateAnimation.play(indicatorsAlpha);                                                       
3433                                                                                                          
3434             if (material) {                                                                              
3435                 final View allApps = getAllAppsButton();                                                 
3436                 int allAppsButtonSize = LauncherAppState.getInstance().                                  
3437                         getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                     
3438                 float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                            
3439                 Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,         
3440                                 height / 2, startRadius, revealRadius);                                  
3441                 reveal.setDuration(revealDuration);                                                      
3442                 reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                           
3443                                                                                                          
3444                 reveal.addListener(new AnimatorListenerAdapter() {                                       
3445                     public void onAnimationStart(Animator animation) {                                   
3446                         if (!isWidgetTray) {                                                             
3447                             allApps.setVisibility(View.INVISIBLE);                                       
3448                         }                                                                                
3449                     }                                                                                    
3450                     public void onAnimationEnd(Animator animation) {                                     
3451                         if (!isWidgetTray) {                                                             
3452                             allApps.setVisibility(View.VISIBLE);                                         
3453                         }                                                                                
3454                     }                                                                                    
3455                 });                                                                                      
3456                 mStateAnimation.play(reveal);                                                            
3457             }                                                                                            
3458                                                                                                          
3459             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3460                 @Override                                                                                
3461                 public void onAnimationEnd(Animator animation) {                                         
3462                     dispatchOnLauncherTransitionEnd(fromView, animated, false);                          
3463                     dispatchOnLauncherTransitionEnd(toView, animated, false);                            
3464                                                                                                          
3465                     revealView.setVisibility(View.INVISIBLE);                                            
3466                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3467                     if (page != null) {                                                                  
3468                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3469                     }                                                                                    
3470                     content.setPageBackgroundsVisible(true);                                             
3471                                                                                                          
3472                     // Hide the search bar                                                               
3473                     if (mSearchDropTargetBar != null) {                                                  
3474                         mSearchDropTargetBar.hideSearchBar(false);                                       
3475                     }                                                                                    
3476                 }                                                                                        
3477                                                                                                          
3478             });                                                                                          
3479                                                                                                          
3480             if (workspaceAnim != null) {                                                                 
3481                 mStateAnimation.play(workspaceAnim);                                                     
3482             }                                                                                            
3483                                                                                                          
3484             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3485             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3486             final AnimatorSet stateAnimation = mStateAnimation;                                          
3487             final Runnable startAnimRunnable = new Runnable() {                                          
3488                 public void run() {                                                                      
3489                     // Check that mStateAnimation hasn't changed while                                   
3490                     // we waited for a layout/draw pass                                                  
3491                     if (mStateAnimation != stateAnimation)                                               
3492                         return;                                                                          
3493                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3494                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3495                                                                                                          
3496                     revealView.setAlpha(initAlpha);                                                      
3497                     if (Utilities.isLmpOrAbove()) {                                                      
3498                         for (int i = 0; i < layerViews.size(); i++) {                                    
3499                             View v = layerViews.get(i);                                                  
3500                             if (v != null) {                                                             
3501                                 boolean attached = true;                                                 
3502                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3503                                     attached = v.isAttachedToWindow();                                   
3504                                 }                                                                        
3505                                 if (attached) v.buildLayer();                                            
3506                             }                                                                            
3507                         }                                                                                
3508                     }                                                                                    
3509                     mStateAnimation.start();                                                             
3510                 }                                                                                        
3511             };                                                                                           
3512             toView.bringToFront();                                                                       
3513             toView.setVisibility(View.VISIBLE);                                                          
3514             toView.post(startAnimRunnable);                                                              
3515         } else {                                                                                         
3516             toView.setTranslationX(0.0f);                                                                
3517             toView.setTranslationY(0.0f);                                                                
3518             toView.setScaleX(1.0f);                                                                      
3519             toView.setScaleY(1.0f);                                                                      
3520             toView.setVisibility(View.VISIBLE);                                                          
3521             toView.bringToFront();                                                                       
3522                                                                                                          
3523             if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                      
3524                 // Hide the search bar                                                                   
3525                 if (mSearchDropTargetBar != null) {                                                      
3526                     mSearchDropTargetBar.hideSearchBar(false);                                           
3527                 }                                                                                        
3528             }                                                                                            
3529             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3530             dispatchOnLauncherTransitionStart(fromView, animated, false);                                
3531             dispatchOnLauncherTransitionEnd(fromView, animated, false);                                  
3532             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3533             dispatchOnLauncherTransitionStart(toView, animated, false);                                  
3534             dispatchOnLauncherTransitionEnd(toView, animated, false);                                    
3535         }                                                                                                
3536     }                                                                                                    
3537                                                                                                          
3538     /**                                                                                                  
3539      * Zoom the camera back into the workspace, hiding 'fromView'.                                       
3540      * This is the opposite of showAppsCustomizeHelper.                                                  
3541      * @param animated If true, the transition will be animated.                                         
3542      */                                                                                                  
3543     private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                
3544             final boolean springLoaded, final Runnable onCompleteRunnable) {                             
3545                                                                                                          
3546         if (mStateAnimation != null) {                                                                   
3547             mStateAnimation.setDuration(0);                                                              
3548             mStateAnimation.cancel();                                                                    
3549             mStateAnimation = null;                                                                      
3550         }                                                                                                
3551                                                                                                          
3552         boolean material = Utilities.isLmpOrAbove();                                                     
3553         Resources res = getResources();                                                                  
3554                                                                                                          
3555         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                  
3556         final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);           
3557         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);            
3558         final int itemsAlphaStagger =                                                                    
3559                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3560                                                                                                          
3561         final float scaleFactor = (float)                                                                
3562                 res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                           
3563         final View fromView = mAppsCustomizeTabHost;                                                     
3564         final View toView = mWorkspace;                                                                  
3565         Animator workspaceAnim = null;                                                                   
3566         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3567                                                                                                          
3568         if (toState == Workspace.State.NORMAL) {                                                         
3569             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3570                     toState, animated, layerViews);                                                      
3571         } else if (toState == Workspace.State.SPRING_LOADED ||                                           
3572                 toState == Workspace.State.OVERVIEW) {                                                   
3573             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3574                     toState, animated, layerViews);                                                      
3575         }                                                                                                
3576                                                                                                          
3577         // If for some reason our views aren't initialized, don't animate                                
3578         boolean initialized = getAllAppsButton() != null;                                                
3579                                                                                                          
3580         if (animated && initialized) {                                                                   
3581             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3582             if (workspaceAnim != null) {                                                                 
3583                 mStateAnimation.play(workspaceAnim);                                                     
3584             }                                                                                            
3585                                                                                                          
3586             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3587                     fromView.findViewById(R.id.apps_customize_pane_content);                             
3588                                                                                                          
3589             final View page = content.getPageAt(content.getNextPage());                                  
3590                                                                                                          
3591             // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases        
3592             int count = content.getChildCount();                                                         
3593             for (int i = 0; i < count; i++) {                                                            
3594                 View child = content.getChildAt(i);                                                      
3595                 if (child != page) {                                                                     
3596                     child.setVisibility(View.INVISIBLE);                                                 
3597                 }                                                                                        
3598             }                                                                                            
3599             final View revealView = fromView.findViewById(R.id.fake_page);                               
3600                                                                                                          
3601             // hideAppsCustomizeHelper is called in some cases when it is already hidden                 
3602             // don't perform all these no-op animations. In particularly, this was causing               
3603             // the all-apps button to pop in and out.                                                    
3604             if (fromView.getVisibility() == View.VISIBLE) {                                              
3605                 AppsCustomizePagedView.ContentType contentType = content.getContentType();               
3606                 final boolean isWidgetTray =                                                             
3607                         contentType == AppsCustomizePagedView.ContentType.Widgets;                       
3608                                                                                                          
3609                 if (isWidgetTray) {                                                                      
3610                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));            
3611                 } else {                                                                                 
3612                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                 
3613                 }                                                                                        
3614                                                                                                          
3615                 int width = revealView.getMeasuredWidth();                                               
3616                 int height = revealView.getMeasuredHeight();                                             
3617                 float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);     
3618                                                                                                          
3619                 // Hide the real page background, and swap in the fake one                               
3620                 revealView.setVisibility(View.VISIBLE);                                                  
3621                 content.setPageBackgroundsVisible(false);                                                
3622                                                                                                          
3623                 final View allAppsButton = getAllAppsButton();                                           
3624                 revealView.setTranslationY(0);                                                           
3625                 int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,            
3626                         allAppsButton, null);                                                            
3627                                                                                                          
3628                 float xDrift = 0;                                                                        
3629                 float yDrift = 0;                                                                        
3630                 if (material) {                                                                          
3631                     yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                         
3632                     xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                  
3633                 } else {                                                                                 
3634                     yDrift = 5 * height / 4;                                                             
3635                     xDrift = 0;                                                                          
3636                 }                                                                                        
3637                                                                                                          
3638                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                 
3639                 TimeInterpolator decelerateInterpolator = material ?                                     
3640                         new LogDecelerateInterpolator(100, 0) :                                          
3641                         new LogDecelerateInterpolator(30, 0);                                            
3642                                                                                                          
3643                 // The vertical motion of the apps panel should be delayed by one frame                  
3644                 // from the conceal animation in order to give the right feel. We correpsondingly        
3645                 // shorten the duration so that the slide and conceal end at the same time.              
3646                 ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",       
3647                         0, yDrift);                                                                      
3648                 panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3649                 panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3650                 panelDriftY.setInterpolator(decelerateInterpolator);                                     
3651                 mStateAnimation.play(panelDriftY);                                                       
3652                                                                                                          
3653                 ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",       
3654                         0, xDrift);                                                                      
3655                 panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3656                 panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3657                 panelDriftX.setInterpolator(decelerateInterpolator);                                     
3658                 mStateAnimation.play(panelDriftX);                                                       
3659                                                                                                          
3660                 if (isWidgetTray || !material) {                                                         
3661                     float finalAlpha = material ? 0.4f : 0f;                                             
3662                     revealView.setAlpha(1f);                                                             
3663                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",           
3664                             1f, finalAlpha);                                                             
3665                     panelAlpha.setDuration(revealDuration);                                              
3666                     panelAlpha.setInterpolator(material ? decelerateInterpolator :                       
3667                         new AccelerateInterpolator(1.5f));                                               
3668                     mStateAnimation.play(panelAlpha);                                                    
3669                 }                                                                                        
3670                                                                                                          
3671                 if (page != null) {                                                                      
3672                     page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                   
3673                                                                                                          
3674                     ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",           
3675                             0, yDrift);                                                                  
3676                     page.setTranslationY(0);                                                             
3677                     pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                          
3678                     pageDrift.setInterpolator(decelerateInterpolator);                                   
3679                     pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                     
3680                     mStateAnimation.play(pageDrift);                                                     
3681                                                                                                          
3682                     page.setAlpha(1f);                                                                   
3683                     ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);        
3684                     itemsAlpha.setDuration(100);                                                         
3685                     itemsAlpha.setInterpolator(decelerateInterpolator);                                  
3686                     mStateAnimation.play(itemsAlpha);                                                    
3687                 }                                                                                        
3688                                                                                                          
3689                 View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);         
3690                 pageIndicators.setAlpha(1f);                                                             
3691                 ObjectAnimator indicatorsAlpha =                                                         
3692                         LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                          
3693                 indicatorsAlpha.setDuration(revealDuration);                                             
3694                 indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                       
3695                 mStateAnimation.play(indicatorsAlpha);                                                   
3696                                                                                                          
3697                 width = revealView.getMeasuredWidth();                                                   
3698                                                                                                          
3699                 if (material) {                                                                          
3700                     if (!isWidgetTray) {                                                                 
3701                         allAppsButton.setVisibility(View.INVISIBLE);                                     
3702                     }                                                                                    
3703                     int allAppsButtonSize = LauncherAppState.getInstance().                              
3704                             getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                 
3705                     float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                        
3706                     Animator reveal =                                                                    
3707                             LauncherAnimUtils.createCircularReveal(revealView, width / 2,                
3708                                     height / 2, revealRadius, finalRadius);                              
3709                     reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                       
3710                     reveal.setDuration(revealDuration);                                                  
3711                     reveal.setStartDelay(itemsAlphaStagger);                                             
3712                                                                                                          
3713                     reveal.addListener(new AnimatorListenerAdapter() {                                   
3714                         public void onAnimationEnd(Animator animation) {                                 
3715                             revealView.setVisibility(View.INVISIBLE);                                    
3716                             if (!isWidgetTray) {                                                         
3717                                 allAppsButton.setVisibility(View.VISIBLE);                               
3718                             }                                                                            
3719                         }                                                                                
3720                     });                                                                                  
3721                                                                                                          
3722                     mStateAnimation.play(reveal);                                                        
3723                 }                                                                                        
3724                                                                                                          
3725                 dispatchOnLauncherTransitionPrepare(fromView, animated, true);                           
3726                 dispatchOnLauncherTransitionPrepare(toView, animated, true);                             
3727                 mAppsCustomizeContent.stopScrolling();                                                   
3728             }                                                                                            
3729                                                                                                          
3730             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3731                 @Override                                                                                
3732                 public void onAnimationEnd(Animator animation) {                                         
3733                     fromView.setVisibility(View.GONE);                                                   
3734                     dispatchOnLauncherTransitionEnd(fromView, animated, true);                           
3735                     dispatchOnLauncherTransitionEnd(toView, animated, true);                             
3736                     if (onCompleteRunnable != null) {                                                    
3737                         onCompleteRunnable.run();                                                        
3738                     }                                                                                    
3739                                                                                                          
3740                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3741                     if (page != null) {                                                                  
3742                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3743                     }                                                                                    
3744                     content.setPageBackgroundsVisible(true);                                             
3745                     // Unhide side pages                                                                 
3746                     int count = content.getChildCount();                                                 
3747                     for (int i = 0; i < count; i++) {                                                    
3748                         View child = content.getChildAt(i);                                              
3749                         child.setVisibility(View.VISIBLE);                                               
3750                     }                                                                                    
3751                                                                                                          
3752                     // Reset page transforms                                                             
3753                     if (page != null) {                                                                  
3754                         page.setTranslationX(0);                                                         
3755                         page.setTranslationY(0);                                                         
3756                         page.setAlpha(1);                                                                
3757                     }                                                                                    
3758                     content.setCurrentPage(content.getNextPage());                                       
3759                                                                                                          
3760                     mAppsCustomizeContent.updateCurrentPageScroll();                                     
3761                 }                                                                                        
3762             });                                                                                          
3763                                                                                                          
3764             final AnimatorSet stateAnimation = mStateAnimation;                                          
3765             final Runnable startAnimRunnable = new Runnable() {                                          
3766                 public void run() {                                                                      
3767                     // Check that mStateAnimation hasn't changed while                                   
3768                     // we waited for a layout/draw pass                                                  
3769                     if (mStateAnimation != stateAnimation)                                               
3770                         return;                                                                          
3771                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3772                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3773                                                                                                          
3774                     if (Utilities.isLmpOrAbove()) {                                                      
3775                         for (int i = 0; i < layerViews.size(); i++) {                                    
3776                             View v = layerViews.get(i);                                                  
3777                             if (v != null) {                                                             
3778                                 boolean attached = true;                                                 
3779                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3780                                     attached = v.isAttachedToWindow();                                   
3781                                 }                                                                        
3782                                 if (attached) v.buildLayer();                                            
3783                             }                                                                            
3784                         }                                                                                
3785                     }                                                                                    
3786                     mStateAnimation.start();                                                             
3787                 }                                                                                        
3788             };                                                                                           
3789             fromView.post(startAnimRunnable);                                                            
3790         } else {                                                                                         
3791             fromView.setVisibility(View.GONE);                                                           
3792             dispatchOnLauncherTransitionPrepare(fromView, animated, true);                               
3793             dispatchOnLauncherTransitionStart(fromView, animated, true);                                 
3794             dispatchOnLauncherTransitionEnd(fromView, animated, true);                                   
3795             dispatchOnLauncherTransitionPrepare(toView, animated, true);                                 
3796             dispatchOnLauncherTransitionStart(toView, animated, true);                                   
3797             dispatchOnLauncherTransitionEnd(toView, animated, true);                                     
3798         }                                                                                                
3799     }                                                                                                    
3800                                                                                                          
3801     @Override                                                                                            
3802     public void onTrimMemory(int level) {                                                                
3803         super.onTrimMemory(level);                                                                       
3804         if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                         
3805             mAppsCustomizeTabHost.onTrimMemory();                                                        
3806         }                                                                                                
3807     }                                                                                                    
3808                                                                                                          
3809     protected void showWorkspace(boolean animated) {                                                     
3810         showWorkspace(animated, null);                                                                   
3811     }                                                                                                    
3812                                                                                                          
3813     protected void showWorkspace() {                                                                     
3814         showWorkspace(true);                                                                             
3815     }                                                                                                    
3816                                                                                                          
3817     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3818         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3819             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3820             mWorkspace.setVisibility(View.VISIBLE);                                                      
3821             hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);        
3822                                                                                                          
3823             // Show the search bar (only animate if we were showing the drop target bar in spring        
3824             // loaded mode)                                                                              
3825             if (mSearchDropTargetBar != null) {                                                          
3826                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3827             }                                                                                            
3828                                                                                                          
3829             // Set focus to the AppsCustomize button                                                     
3830             if (mAllAppsButton != null) {                                                                
3831                 mAllAppsButton.requestFocus();                                                           
3832             }                                                                                            
3833         }                                                                                                
3834                                                                                                          
3835         // Change the state *after* we've called all the transition code                                 
3836         mState = State.WORKSPACE;                                                                        
3837                                                                                                          
3838         // Resume the auto-advance of widgets                                                            
3839         mUserPresent = true;                                                                             
3840         updateRunning();                                                                                 
3841                                                                                                          
3842         // Send an accessibility event to announce the context change                                    
3843         getWindow().getDecorView()                                                                       
3844                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3845                                                                                                          
3846         onWorkspaceShown(animated);                                                                      
3847     }                                                                                                    
3848                                                                                                          
3849     void showOverviewMode(boolean animated) {                                                            
3850         mWorkspace.setVisibility(View.VISIBLE);                                                          
3851         hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                        
3852         mState = State.WORKSPACE;                                                                        
3853         onWorkspaceShown(animated);                                                                      
3854     }                                                                                                    
3855                                                                                                          
3856     public void onWorkspaceShown(boolean animated) {                                                     
3857     }                                                                                                    
3858                                                                                                          
3859     void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                   
3860                      boolean resetPageToZero) {                                                          
3861         if (mState != State.WORKSPACE) return;                                                           
3862                                                                                                          
3863         if (resetPageToZero) {                                                                           
3864             mAppsCustomizeTabHost.reset();                                                               
3865         }                                                                                                
3866         showAppsCustomizeHelper(animated, false, contentType);                                           
3867         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3868             @Override                                                                                    
3869             public void run() {                                                                          
3870                 // We post this in-case the all apps view isn't yet constructed.                         
3871                 mAppsCustomizeTabHost.requestFocus();                                                    
3872             }                                                                                            
3873         });                                                                                              
3874                                                                                                          
3875         // Change the state *after* we've called all the transition code                                 
3876         mState = State.APPS_CUSTOMIZE;                                                                   
3877                                                                                                          
3878         // Pause the auto-advance of widgets until we are out of AllApps                                 
3879         mUserPresent = false;                                                                            
3880         updateRunning();                                                                                 
3881         closeFolder();                                                                                   
3882                                                                                                          
3883         // Send an accessibility event to announce the context change                                    
3884         getWindow().getDecorView()                                                                       
3885                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3886     }                                                                                                    
3887                                                                                                          
3888     void enterSpringLoadedDragMode() {                                                                   
3889         if (isAllAppsVisible()) {                                                                        
3890             hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                    
3891             mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                 
3892         }                                                                                                
3893     }                                                                                                    
3894                                                                                                          
3895     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3896             final Runnable onCompleteRunnable) {                                                         
3897         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                        
3898                                                                                                          
3899         mHandler.postDelayed(new Runnable() {                                                            
3900             @Override                                                                                    
3901             public void run() {                                                                          
3902                 if (successfulDrop) {                                                                    
3903                     // Before we show workspace, hide all apps again because                             
3904                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3905                     // clean up our state transition functions                                           
3906                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3907                     showWorkspace(true, onCompleteRunnable);                                             
3908                 } else {                                                                                 
3909                     exitSpringLoadedDragMode();                                                          
3910                 }                                                                                        
3911             }                                                                                            
3912         }, delay);                                                                                       
3913     }                                                                                                    
3914                                                                                                          
3915     void exitSpringLoadedDragMode() {                                                                    
3916         if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3917             final boolean animated = true;                                                               
3918             final boolean springLoaded = true;                                                           
3919             showAppsCustomizeHelper(animated, springLoaded);                                             
3920             mState = State.APPS_CUSTOMIZE;                                                               
3921         }                                                                                                
3922         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3923     }                                                                                                    
3924                                                                                                          
3925     void lockAllApps() {                                                                                 
3926         // TODO                                                                                          
3927     }                                                                                                    
3928                                                                                                          
3929     void unlockAllApps() {                                                                               
3930         // TODO                                                                                          
3931     }                                                                                                    
3932                                                                                                          
3933     /**                                                                                                  
3934      * Hides the hotseat area.                                                                           
3935      */                                                                                                  
3936     void hideHotseat(boolean animated) {                                                                 
3937         if (!LauncherAppState.getInstance().isScreenLarge()) {                                           
3938             if (animated) {                                                                              
3939                 if (mHotseat.getAlpha() != 0f) {                                                         
3940                     int duration = 0;                                                                    
3941                     if (mSearchDropTargetBar != null) {                                                  
3942                         duration = mSearchDropTargetBar.getTransitionOutDuration();                      
3943                     }                                                                                    
3944                     mHotseat.animate().alpha(0f).setDuration(duration);                                  
3945                 }                                                                                        
3946             } else {                                                                                     
3947                 mHotseat.setAlpha(0f);                                                                   
3948             }                                                                                            
3949         }                                                                                                
3950     }                                                                                                    
3951                                                                                                          
3952     /**                                                                                                  
3953      * Add an item from all apps or customize onto the given workspace screen.                           
3954      * If layout is null, add to the current screen.                                                     
3955      */                                                                                                  
3956     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                           
3957         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                     
3958             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
3959         }                                                                                                
3960     }                                                                                                    
3961                                                                                                          
3962     /** Maps the current orientation to an index for referencing orientation correct global icons */     
3963     private int getCurrentOrientationIndexForGlobalIcons() {                                             
3964         // default - 0, landscape - 1                                                                    
3965         switch (getResources().getConfiguration().orientation) {                                         
3966         case Configuration.ORIENTATION_LANDSCAPE:                                                        
3967             return 1;                                                                                    
3968         default:                                                                                         
3969             return 0;                                                                                    
3970         }                                                                                                
3971     }                                                                                                    
3972                                                                                                          
3973     private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {    
3974         try {                                                                                            
3975             PackageManager packageManager = getPackageManager();                                         
3976             // Look for the toolbar icon specified in the activity meta-data                             
3977             Bundle metaData = packageManager.getActivityInfo(                                            
3978                     activityName, PackageManager.GET_META_DATA).metaData;                                
3979             if (metaData != null) {                                                                      
3980                 int iconResId = metaData.getInt(resourceName);                                           
3981                 if (iconResId != 0) {                                                                    
3982                     Resources res = packageManager.getResourcesForActivity(activityName);                
3983                     return res.getDrawable(iconResId);                                                   
3984                 }                                                                                        
3985             }                                                                                            
3986         } catch (NameNotFoundException e) {                                                              
3987             // This can happen if the activity defines an invalid drawable                               
3988             Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +           
3989                     " not found", e);                                                                    
3990         } catch (Resources.NotFoundException nfe) {                                                      
3991             // This can happen if the activity defines an invalid drawable                               
3992             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),        
3993                     nfe);                                                                                
3994         }                                                                                                
3995         return null;                                                                                     
3996     }                                                                                                    
3997                                                                                                          
3998     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3999     private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                         
4000             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
4001             String toolbarResourceName) {                                                                
4002         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
4003         Resources r = getResources();                                                                    
4004         int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                            
4005         int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                           
4006                                                                                                          
4007         TextView button = (TextView) findViewById(buttonId);                                             
4008         // If we were unable to find the icon via the meta-data, use a generic one                       
4009         if (toolbarIcon == null) {                                                                       
4010             toolbarIcon = r.getDrawable(fallbackDrawableId);                                             
4011             toolbarIcon.setBounds(0, 0, w, h);                                                           
4012             if (button != null) {                                                                        
4013                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
4014             }                                                                                            
4015             return null;                                                                                 
4016         } else {                                                                                         
4017             toolbarIcon.setBounds(0, 0, w, h);                                                           
4018             if (button != null) {                                                                        
4019                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
4020             }                                                                                            
4021             return toolbarIcon.getConstantState();                                                       
4022         }                                                                                                
4023     }                                                                                                    
4024                                                                                                          
4025     // if successful in getting icon, return it; otherwise, set button to use default drawable           
4026     private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                             
4027             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
4028             String toolbarResourceName) {                                                                
4029         ImageView button = (ImageView) findViewById(buttonId);                                           
4030         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
4031                                                                                                          
4032         if (button != null) {                                                                            
4033             // If we were unable to find the icon via the meta-data, use a                               
4034             // generic one                                                                               
4035             if (toolbarIcon == null) {                                                                   
4036                 button.setImageResource(fallbackDrawableId);                                             
4037             } else {                                                                                     
4038                 button.setImageDrawable(toolbarIcon);                                                    
4039             }                                                                                            
4040         }                                                                                                
4041                                                                                                          
4042         return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                              
4043                                                                                                          
4044     }                                                                                                    
4045                                                                                                          
4046     private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                
4047         TextView button = (TextView) findViewById(buttonId);                                             
4048         button.setCompoundDrawables(d, null, null, null);                                                
4049     }                                                                                                    
4050                                                                                                          
4051     private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                      
4052         ImageView button = (ImageView) findViewById(buttonId);                                           
4053         button.setImageDrawable(d.newDrawable(getResources()));                                          
4054     }                                                                                                    
4055                                                                                                          
4056     private void invalidatePressedFocusedStates(View container, View button) {                           
4057         if (container instanceof HolographicLinearLayout) {                                              
4058             HolographicLinearLayout layout = (HolographicLinearLayout) container;                        
4059             layout.invalidatePressedFocusedStates();                                                     
4060         } else if (button instanceof HolographicImageView) {                                             
4061             HolographicImageView view = (HolographicImageView) button;                                   
4062             view.invalidatePressedFocusedStates();                                                       
4063         }                                                                                                
4064     }                                                                                                    
4065                                                                                                          
4066     public View getQsbBar() {                                                                            
4067         if (mQsb == null) {                                                                              
4068             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                         
4069             mSearchDropTargetBar.addView(mQsb);                                                          
4070         }                                                                                                
4071         return mQsb;                                                                                     
4072     }                                                                                                    
4073                                                                                                          
4074     protected boolean updateGlobalSearchIcon() {                                                         
4075         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4076         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                     
4077         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4078         final View voiceButton = findViewById(R.id.voice_button);                                        
4079                                                                                                          
4080         final SearchManager searchManager =                                                              
4081                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4082         ComponentName activityName = searchManager.getGlobalSearchActivity();                            
4083         if (activityName != null) {                                                                      
4084             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4085             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                           
4086                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,             
4087                     TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                  
4088             if (sGlobalSearchIcon[coi] == null) {                                                        
4089                 sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                       
4090                         R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,         
4091                         TOOLBAR_ICON_METADATA_NAME);                                                     
4092             }                                                                                            
4093                                                                                                          
4094             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);        
4095             searchButton.setVisibility(View.VISIBLE);                                                    
4096             invalidatePressedFocusedStates(searchButtonContainer, searchButton);                         
4097             return true;                                                                                 
4098         } else {                                                                                         
4099             // We disable both search and voice search when there is no global search provider           
4100             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);           
4101             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4102             if (searchButton != null) searchButton.setVisibility(View.GONE);                             
4103             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4104             updateVoiceButtonProxyVisible(false);                                                        
4105             return false;                                                                                
4106         }                                                                                                
4107     }                                                                                                    
4108                                                                                                          
4109     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                    
4110         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4111         final View searchButton = (ImageView) findViewById(R.id.search_button);                          
4112         updateButtonWithDrawable(R.id.search_button, d);                                                 
4113         invalidatePressedFocusedStates(searchButtonContainer, searchButton);                             
4114     }                                                                                                    
4115                                                                                                          
4116     protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                     
4117         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4118         final View voiceButton = findViewById(R.id.voice_button);                                        
4119                                                                                                          
4120         // We only show/update the voice search icon if the search icon is enabled as well               
4121         final SearchManager searchManager =                                                              
4122                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4123         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
4124                                                                                                          
4125         ComponentName activityName = null;                                                               
4126         if (globalSearchActivity != null) {                                                              
4127             // Check if the global search activity handles voice search                                  
4128             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4129             intent.setPackage(globalSearchActivity.getPackageName());                                    
4130             activityName = intent.resolveActivity(getPackageManager());                                  
4131         }                                                                                                
4132                                                                                                          
4133         if (activityName == null) {                                                                      
4134             // Fallback: check if an activity other than the global search activity                      
4135             // resolves this                                                                             
4136             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4137             activityName = intent.resolveActivity(getPackageManager());                                  
4138         }                                                                                                
4139         if (searchVisible && activityName != null) {                                                     
4140             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4141             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                            
4142                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,               
4143                     TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                            
4144             if (sVoiceSearchIcon[coi] == null) {                                                         
4145                 sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                        
4146                         R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,           
4147                         TOOLBAR_ICON_METADATA_NAME);                                                     
4148             }                                                                                            
4149             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);          
4150             voiceButton.setVisibility(View.VISIBLE);                                                     
4151             updateVoiceButtonProxyVisible(false);                                                        
4152             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                           
4153             return true;                                                                                 
4154         } else {                                                                                         
4155             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4156             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4157             updateVoiceButtonProxyVisible(false);                                                        
4158             return false;                                                                                
4159         }                                                                                                
4160     }                                                                                                    
4161                                                                                                          
4162     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                     
4163         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4164         final View voiceButton = findViewById(R.id.voice_button);                                        
4165         updateButtonWithDrawable(R.id.voice_button, d);                                                  
4166         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                               
4167     }                                                                                                    
4168                                                                                                          
4169     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                    
4170         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                             
4171         if (voiceButtonProxy != null) {                                                                  
4172             boolean visible = !forceDisableVoiceButtonProxy &&                                           
4173                     mWorkspace.shouldVoiceButtonProxyBeVisible();                                        
4174             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                          
4175             voiceButtonProxy.bringToFront();                                                             
4176         }                                                                                                
4177     }                                                                                                    
4178                                                                                                          
4179     /**                                                                                                  
4180      * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button🔵
4181      * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                      
4182      */                                                                                                  
4183     public void disableVoiceButtonProxy(boolean disabled) {                                              
4184         updateVoiceButtonProxyVisible(disabled);                                                         
4185     }                                                                                                    
4186                                                                                                          
4187     @Override                                                                                            
4188     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
4189         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
4190         final List<CharSequence> text = event.getText();                                                 
4191         text.clear();                                                                                    
4192         // Populate event with a fake title based on the current state.                                  
4193         if (mState == State.APPS_CUSTOMIZE) {                                                            
4194             text.add(mAppsCustomizeTabHost.getContentTag());                                             
4195         } else {                                                                                         
4196             text.add(getString(R.string.all_apps_home_button_label));                                    
4197         }                                                                                                
4198         return result;                                                                                   
4199     }                                                                                                    
4200                                                                                                          
4201     /**                                                                                                  
4202      * Receives notifications when system dialogs are to be closed.                                      
4203      */                                                                                                  
4204     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
4205         @Override                                                                                        
4206         public void onReceive(Context context, Intent intent) {                                          
4207             closeSystemDialogs();                                                                        
4208         }                                                                                                
4209     }                                                                                                    
4210                                                                                                          
4211     /**                                                                                                  
4212      * Receives notifications whenever the appwidgets are reset.                                         
4213      */                                                                                                  
4214     private class AppWidgetResetObserver extends ContentObserver {                                       
4215         public AppWidgetResetObserver() {                                                                
4216             super(new Handler());                                                                        
4217         }                                                                                                
4218                                                                                                          
4219         @Override                                                                                        
4220         public void onChange(boolean selfChange) {                                                       
4221             onAppWidgetReset();                                                                          
4222         }                                                                                                
4223     }                                                                                                    
4224                                                                                                          
4225     /**                                                                                                  
4226      * If the activity is currently paused, signal that we need to run the passed Runnable               
4227      * in onResume.                                                                                      
4228      *                                                                                                   
4229      * This needs to be called from incoming places where resources might have been loaded               
4230      * while we are paused.  That is becaues the Configuration might be wrong                            
4231      * when we're not running, and if it comes back to what it was when we                               
4232      * were paused, we are not restarted.                                                                
4233      *                                                                                                   
4234      * Implementation of the method from LauncherModel.Callbacks.                                        
4235      *                                                                                                   
4236      * @return true if we are currently paused.  The caller might be able to                             
4237      * skip some work in that case since we will come back again.                                        
4238      */                                                                                                  
4239     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
4240         if (mPaused) {                                                                                   
4241             Log.i(TAG, "Deferring update until onResume");                                               
4242             if (deletePreviousRunnables) {                                                               
4243                 while (mBindOnResumeCallbacks.remove(run)) {                                             
4244                 }                                                                                        
4245             }                                                                                            
4246             mBindOnResumeCallbacks.add(run);                                                             
4247             return true;                                                                                 
4248         } else {                                                                                         
4249             return false;                                                                                
4250         }                                                                                                
4251     }                                                                                                    
4252                                                                                                          
4253     private boolean waitUntilResume(Runnable run) {                                                      
4254         return waitUntilResume(run, false);                                                              
4255     }                                                                                                    
4256                                                                                                          
4257     public void addOnResumeCallback(Runnable run) {                                                      
4258         mOnResumeCallbacks.add(run);                                                                     
4259     }                                                                                                    
4260                                                                                                          
4261     /**                                                                                                  
4262      * If the activity is currently paused, signal that we need to re-run the loader                     
4263      * in onResume.                                                                                      
4264      *                                                                                                   
4265      * This needs to be called from incoming places where resources might have been loaded               
4266      * while we are paused.  That is becaues the Configuration might be wrong                            
4267      * when we're not running, and if it comes back to what it was when we                               
4268      * were paused, we are not restarted.                                                                
4269      *                                                                                                   
4270      * Implementation of the method from LauncherModel.Callbacks.                                        
4271      *                                                                                                   
4272      * @return true if we are currently paused.  The caller might be able to                             
4273      * skip some work in that case since we will come back again.                                        
4274      */                                                                                                  
4275     public boolean setLoadOnResume() {                                                                   
4276         if (mPaused) {                                                                                   
4277             Log.i(TAG, "setLoadOnResume");                                                               
4278             mOnResumeNeedsLoad = true;                                                                   
4279             return true;                                                                                 
4280         } else {                                                                                         
4281             return false;                                                                                
4282         }                                                                                                
4283     }                                                                                                    
4284                                                                                                          
4285     /**                                                                                                  
4286      * Implementation of the method from LauncherModel.Callbacks.                                        
4287      */                                                                                                  
4288     public int getCurrentWorkspaceScreen() {                                                             
4289         if (mWorkspace != null) {                                                                        
4290             return mWorkspace.getCurrentPage();                                                          
4291         } else {                                                                                         
4292             return SCREEN_COUNT / 2;                                                                     
4293         }                                                                                                
4294     }                                                                                                    
4295                                                                                                          
4296     /**                                                                                                  
4297      * Refreshes the shortcuts shown on the workspace.                                                   
4298      *                                                                                                   
4299      * Implementation of the method from LauncherModel.Callbacks.                                        
4300      */                                                                                                  
4301     public void startBinding() {                                                                         
4302         setWorkspaceLoading(true);                                                                       
4303                                                                                                          
4304         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4305         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4306         // from scratch again                                                                            
4307         mBindOnResumeCallbacks.clear();                                                                  
4308                                                                                                          
4309         // Clear the workspace because it's going to be rebound                                          
4310         mWorkspace.clearDropTargets();                                                                   
4311         mWorkspace.removeAllWorkspaceScreens();                                                          
4312                                                                                                          
4313         mWidgetsToAdvance.clear();                                                                       
4314         if (mHotseat != null) {                                                                          
4315             mHotseat.resetLayout();                                                                      
4316         }                                                                                                
4317     }                                                                                                    
4318                                                                                                          
4319     @Override                                                                                            
4320     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4321         bindAddScreens(orderedScreenIds);                                                                
4322                                                                                                          
4323         // If there are no screens, we need to have an empty screen                                      
4324         if (orderedScreenIds.size() == 0) {                                                              
4325             mWorkspace.addExtraEmptyScreen();                                                            
4326         }                                                                                                
4327                                                                                                          
4328         // Create the custom content page (this call updates mDefaultScreen which calls                  
4329         // setCurrentPage() so ensure that all pages are added before calling this).                     
4330         if (hasCustomContentToLeft()) {                                                                  
4331             mWorkspace.createCustomContentContainer();                                                   
4332             populateCustomContentContainer();                                                            
4333         }                                                                                                
4334     }                                                                                                    
4335                                                                                                          
4336     @Override                                                                                            
4337     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4338         // Log to disk                                                                                   
4339         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4340         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4341                 TextUtils.join(", ", orderedScreenIds), true);                                           
4342         int count = orderedScreenIds.size();                                                             
4343         for (int i = 0; i < count; i++) {                                                                
4344             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4345         }                                                                                                
4346     }                                                                                                    
4347                                                                                                          
4348     private boolean shouldShowWeightWatcher() {                                                          
4349         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4350         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4351         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4352                                                                                                          
4353         return show;                                                                                     
4354     }                                                                                                    
4355                                                                                                          
4356     private void toggleShowWeightWatcher() {                                                             
4357         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4358         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4359         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4360                                                                                                          
4361         show = !show;                                                                                    
4362                                                                                                          
4363         SharedPreferences.Editor editor = sp.edit();                                                     
4364         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4365         editor.commit();                                                                                 
4366                                                                                                          
4367         if (mWeightWatcher != null) {                                                                    
4368             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4369         }                                                                                                
4370     }                                                                                                    
4371                                                                                                          
4372     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4373                               final ArrayList<ItemInfo> addNotAnimated,                                  
4374                               final ArrayList<ItemInfo> addAnimated,                                     
4375                               final ArrayList<AppInfo> addedApps) {                                      
4376         Runnable r = new Runnable() {                                                                    
4377             public void run() {                                                                          
4378                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4379             }                                                                                            
4380         };                                                                                               
4381         if (waitUntilResume(r)) {                                                                        
4382             return;                                                                                      
4383         }                                                                                                
4384                                                                                                          
4385         // Add the new screens                                                                           
4386         if (newScreens != null) {                                                                        
4387             bindAddScreens(newScreens);                                                                  
4388         }                                                                                                
4389                                                                                                          
4390         // We add the items without animation on non-visible pages, and with                             
4391         // animations on the new page (which we will try and snap to).                                   
4392         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
4393             bindItems(addNotAnimated, 0,                                                                 
4394                     addNotAnimated.size(), false);                                                       
4395         }                                                                                                
4396         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
4397             bindItems(addAnimated, 0,                                                                    
4398                     addAnimated.size(), true);                                                           
4399         }                                                                                                
4400                                                                                                          
4401         // Remove the extra empty screen                                                                 
4402         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4403                                                                                                          
4404         if (!LauncherAppState.isDisableAllApps() &&                                                      
4405                 addedApps != null && mAppsCustomizeContent != null) {                                    
4406             mAppsCustomizeContent.addApps(addedApps);                                                    
4407         }                                                                                                
4408     }                                                                                                    
4409                                                                                                          
4410     /**                                                                                                  
4411      * Bind the items start-end from the list.                                                           
4412      *                                                                                                   
4413      * Implementation of the method from LauncherModel.Callbacks.                                        
4414      */                                                                                                  
4415     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4416                           final boolean forceAnimateIcons) {                                             
4417         Runnable r = new Runnable() {                                                                    
4418             public void run() {                                                                          
4419                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4420             }                                                                                            
4421         };                                                                                               
4422         if (waitUntilResume(r)) {                                                                        
4423             return;                                                                                      
4424         }                                                                                                
4425                                                                                                          
4426         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4427         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4428         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4429         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4430         Workspace workspace = mWorkspace;                                                                
4431         long newShortcutsScreenId = -1;                                                                  
4432         for (int i = start; i < end; i++) {                                                              
4433             final ItemInfo item = shortcuts.get(i);                                                      
4434                                                                                                          
4435             // Short circuit if we are loading dock items for a configuration which has no dock          
4436             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4437                     mHotseat == null) {                                                                  
4438                 continue;                                                                                
4439             }                                                                                            
4440                                                                                                          
4441             switch (item.itemType) {                                                                     
4442                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4443                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4444                     ShortcutInfo info = (ShortcutInfo) item;                                             
4445                     View shortcut = createShortcut(info);                                                
4446                                                                                                          
4447                     /*                                                                                   
4448                      * TODO: FIX collision case                                                          
4449                      */                                                                                  
4450                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4451                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4452                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4453                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4454                             Object tag = v.getTag();                                                     
4455                             String desc = "Collision while binding workspace item: " + item              
4456                                     + ". Collides with " + tag;                                          
4457                             if (LauncherAppState.isDogfoodBuild()) {                                     
4458                                 throw (new RuntimeException(desc));                                      
4459                             } else {                                                                     
4460                                 Log.d(TAG, desc);                                                        
4461                             }                                                                            
4462                         }                                                                                
4463                     }                                                                                    
4464                                                                                                          
4465                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4466                             item.cellY, 1, 1);                                                           
4467                     if (animateIcons) {                                                                  
4468                         // Animate all the applications up now                                           
4469                         shortcut.setAlpha(0f);                                                           
4470                         shortcut.setScaleX(0f);                                                          
4471                         shortcut.setScaleY(0f);                                                          
4472                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4473                         newShortcutsScreenId = item.screenId;                                            
4474                     }                                                                                    
4475                     break;                                                                               
4476                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4477                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4478                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4479                             (FolderInfo) item, mIconCache);                                              
4480                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4481                             item.cellY, 1, 1);                                                           
4482                     break;                                                                               
4483                 default:                                                                                 
4484                     throw new RuntimeException("Invalid Item Type");                                     
4485             }                                                                                            
4486         }                                                                                                
4487                                                                                                          
4488         if (animateIcons) {                                                                              
4489             // Animate to the correct page                                                               
4490             if (newShortcutsScreenId > -1) {                                                             
4491                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4492                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4493                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4494                     public void run() {                                                                  
4495                         anim.playTogether(bounceAnims);                                                  
4496                         anim.start();                                                                    
4497                     }                                                                                    
4498                 };                                                                                       
4499                 if (newShortcutsScreenId != currentScreenId) {                                           
4500                     // We post the animation slightly delayed to prevent slowdowns                       
4501                     // when we are loading right after we return to launcher.                            
4502                     mWorkspace.postDelayed(new Runnable() {                                              
4503                         public void run() {                                                              
4504                             if (mWorkspace != null) {                                                    
4505                                 mWorkspace.snapToPage(newScreenIndex);                                   
4506                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4507                                         NEW_APPS_ANIMATION_DELAY);                                       
4508                             }                                                                            
4509                         }                                                                                
4510                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4511                 } else {                                                                                 
4512                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4513                 }                                                                                        
4514             }                                                                                            
4515         }                                                                                                
4516         workspace.requestLayout();                                                                       
4517     }                                                                                                    
4518                                                                                                          
4519     /**                                                                                                  
4520      * Implementation of the method from LauncherModel.Callbacks.                                        
4521      */                                                                                                  
4522     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4523         Runnable r = new Runnable() {                                                                    
4524             public void run() {                                                                          
4525                 bindFolders(folders);                                                                    
4526             }                                                                                            
4527         };                                                                                               
4528         if (waitUntilResume(r)) {                                                                        
4529             return;                                                                                      
4530         }                                                                                                
4531         sFolders.clear();                                                                                
4532         sFolders.putAll(folders);                                                                        
4533     }                                                                                                    
4534                                                                                                          
4535     /**                                                                                                  
4536      * Add the views for a widget to the workspace.                                                      
4537      *                                                                                                   
4538      * Implementation of the method from LauncherModel.Callbacks.                                        
4539      */                                                                                                  
4540     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4541         Runnable r = new Runnable() {                                                                    
4542             public void run() {                                                                          
4543                 bindAppWidget(item);                                                                     
4544             }                                                                                            
4545         };                                                                                               
4546         if (waitUntilResume(r)) {                                                                        
4547             return;                                                                                      
4548         }                                                                                                
4549                                                                                                          
4550         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4551         if (DEBUG_WIDGETS) {                                                                             
4552             Log.d(TAG, "bindAppWidget: " + item);                                                        
4553         }                                                                                                
4554         final Workspace workspace = mWorkspace;                                                          
4555                                                                                                          
4556         AppWidgetProviderInfo appWidgetInfo;                                                             
4557         if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&               
4558                 ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                 
4559                                                                                                          
4560             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);      
4561             if (appWidgetInfo == null) {                                                                 
4562                 if (DEBUG_WIDGETS) {                                                                     
4563                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4564                             + " belongs to component " + item.providerName                               
4565                             + ", as the povider is null");                                               
4566                 }                                                                                        
4567                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4568                 return;                                                                                  
4569             }                                                                                            
4570             // Note: This assumes that the id remap broadcast is received before this step.              
4571             // If that is not the case, the id remap will be ignored and user may see the                
4572             // click to setup view.                                                                      
4573             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);      
4574             pendingInfo.spanX = item.spanX;                                                              
4575             pendingInfo.spanY = item.spanY;                                                              
4576             pendingInfo.minSpanX = item.minSpanX;                                                        
4577             pendingInfo.minSpanY = item.minSpanY;                                                        
4578             Bundle options =                                                                             
4579                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
4580                                                                                                          
4581             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4582             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4583                     newWidgetId, appWidgetInfo, options);                                                
4584                                                                                                          
4585             // TODO consider showing a permission dialog when the widget is clicked.                     
4586             if (!success) {                                                                              
4587                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4588                 if (DEBUG_WIDGETS) {                                                                     
4589                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4590                             + " belongs to component " + item.providerName                               
4591                             + ", as the launcher is unable to bing a new widget id");                    
4592                 }                                                                                        
4593                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4594                 return;                                                                                  
4595             }                                                                                            
4596                                                                                                          
4597             item.appWidgetId = newWidgetId;                                                              
4598                                                                                                          
4599             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4600             // the widget is ready to go.                                                                
4601             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4602                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4603                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4604                                                                                                          
4605             LauncherModel.updateItemInDatabase(this, item);                                              
4606         }                                                                                                
4607                                                                                                          
4608         if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                             
4609             final int appWidgetId = item.appWidgetId;                                                    
4610             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
4611             if (DEBUG_WIDGETS) {                                                                         
4612                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidget🔵
4613             }                                                                                            
4614                                                                                                          
4615             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4616         } else {                                                                                         
4617             appWidgetInfo = null;                                                                        
4618             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                    
4619             view.updateIcon(mIconCache);                                                                 
4620             item.hostView = view;                                                                        
4621             item.hostView.updateAppWidget(null);                                                         
4622             item.hostView.setOnClickListener(this);                                                      
4623         }                                                                                                
4624                                                                                                          
4625         item.hostView.setTag(item);                                                                      
4626         item.onBindAppWidget(this);                                                                      
4627                                                                                                          
4628         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4629                 item.cellY, item.spanX, item.spanY, false);                                              
4630         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
4631                                                                                                          
4632         workspace.requestLayout();                                                                       
4633                                                                                                          
4634         if (DEBUG_WIDGETS) {                                                                             
4635             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4636                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4637         }                                                                                                
4638     }                                                                                                    
4639                                                                                                          
4640     /**                                                                                                  
4641      * Restores a pending widget.                                                                        
4642      *                                                                                                   
4643      * @param appWidgetId The app widget id                                                              
4644      * @param cellInfo The position on screen where to create the widget.                                
4645      */                                                                                                  
4646     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4647         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4648         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4649             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4650             return;                                                                                      
4651         }                                                                                                
4652                                                                                                          
4653         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4654         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4655                                                                                                          
4656         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4657         LauncherModel.updateItemInDatabase(this, info);                                                  
4658     }                                                                                                    
4659                                                                                                          
4660     public void onPageBoundSynchronously(int page) {                                                     
4661         mSynchronouslyBoundPages.add(page);                                                              
4662     }                                                                                                    
4663                                                                                                          
4664     /**                                                                                                  
4665      * Callback saying that there aren't any more items to bind.                                         
4666      *                                                                                                   
4667      * Implementation of the method from LauncherModel.Callbacks.                                        
4668      */                                                                                                  
4669     public void finishBindingItems(final boolean upgradePath) {                                          
4670         Runnable r = new Runnable() {                                                                    
4671             public void run() {                                                                          
4672                 finishBindingItems(upgradePath);                                                         
4673             }                                                                                            
4674         };                                                                                               
4675         if (waitUntilResume(r)) {                                                                        
4676             return;                                                                                      
4677         }                                                                                                
4678         if (mSavedState != null) {                                                                       
4679             if (!mWorkspace.hasFocus()) {                                                                
4680                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4681             }                                                                                            
4682             mSavedState = null;                                                                          
4683         }                                                                                                
4684         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4685         setWorkspaceLoading(false);                                                                      
4686         sendLoadingCompleteBroadcastIfNecessary();                                                       
4687         // If we received the result of any pending adds while the loader was running (e.g. the          
4688         // widget configuration forced an orientation change), process them now.                         
4689         if (sPendingAddItem != null) {                                                                   
4690             final long screenId = completeAdd(sPendingAddItem);                                          
4691             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4692             // the screen would be guaranteed to exist after bind, and the page would be set through     
4693             // the workspace restore process.                                                            
4694             mWorkspace.post(new Runnable() {                                                             
4695                 @Override                                                                                
4696                 public void run() {                                                                      
4697                     mWorkspace.snapToScreenId(screenId);                                                 
4698                 }                                                                                        
4699             });                                                                                          
4700             sPendingAddItem = null;                                                                      
4701         }                                                                                                
4702         if (upgradePath) {                                                                               
4703             mWorkspace.getUniqueComponents(true, null);                                                  
4704             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4705         }                                                                                                
4706         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4707         mModel.recheckRestoredItems(this);                                                               
4708     }                                                                                                    
4709                                                                                                          
4710     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4711         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4712             String permission =                                                                          
4713                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4714             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4715             sendBroadcast(intent, permission);                                                           
4716             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4717             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4718             editor.apply();                                                                              
4719         }                                                                                                
4720     }                                                                                                    
4721                                                                                                          
4722     public boolean isAllAppsButtonRank(int rank) {                                                       
4723         if (mHotseat != null) {                                                                          
4724             return mHotseat.isAllAppsButtonRank(rank);                                                   
4725         }                                                                                                
4726         return false;                                                                                    
4727     }                                                                                                    
4728                                                                                                          
4729     private boolean canRunNewAppsAnimation() {                                                           
4730         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4731         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4732     }                                                                                                    
4733                                                                                                          
4734     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4735         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4736                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4737                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4738                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4739         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4740         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4741         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4742         return bounceAnim;                                                                               
4743     }                                                                                                    
4744                                                                                                          
4745     public boolean useVerticalBarLayout() {                                                              
4746         return LauncherAppState.getInstance().getDynamicGrid().                                          
4747                 getDeviceProfile().isVerticalBarLayout();                                                
4748     }                                                                                                    
4749                                                                                                          
4750     protected Rect getSearchBarBounds() {                                                                
4751         return LauncherAppState.getInstance().getDynamicGrid().                                          
4752                 getDeviceProfile().getSearchBarBounds();                                                 
4753     }                                                                                                    
4754                                                                                                          
4755     @Override                                                                                            
4756     public void bindSearchablesChanged() {                                                               
4757         boolean searchVisible = updateGlobalSearchIcon();                                                
4758         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
4759         if (mSearchDropTargetBar != null) {                                                              
4760             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
4761         }                                                                                                
4762     }                                                                                                    
4763                                                                                                          
4764     /**                                                                                                  
4765      * Add the icons for all apps.                                                                       
4766      *                                                                                                   
4767      * Implementation of the method from LauncherModel.Callbacks.                                        
4768      */                                                                                                  
4769     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4770         if (LauncherAppState.isDisableAllApps()) {                                                       
4771             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4772                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4773                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4774                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4775                 }                                                                                        
4776                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4777             }                                                                                            
4778             if (mAppsCustomizeContent != null) {                                                         
4779                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4780                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4781             }                                                                                            
4782         } else {                                                                                         
4783             if (mAppsCustomizeContent != null) {                                                         
4784                 mAppsCustomizeContent.setApps(apps);                                                     
4785                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4786                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4787             }                                                                                            
4788         }                                                                                                
4789     }                                                                                                    
4790                                                                                                          
4791     /**                                                                                                  
4792      * A package was updated.                                                                            
4793      *                                                                                                   
4794      * Implementation of the method from LauncherModel.Callbacks.                                        
4795      */                                                                                                  
4796     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4797         Runnable r = new Runnable() {                                                                    
4798             public void run() {                                                                          
4799                 bindAppsUpdated(apps);                                                                   
4800             }                                                                                            
4801         };                                                                                               
4802         if (waitUntilResume(r)) {                                                                        
4803             return;                                                                                      
4804         }                                                                                                
4805                                                                                                          
4806         if (mWorkspace != null) {                                                                        
4807             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4808         }                                                                                                
4809                                                                                                          
4810         if (!LauncherAppState.isDisableAllApps() &&                                                      
4811                 mAppsCustomizeContent != null) {                                                         
4812             mAppsCustomizeContent.updateApps(apps);                                                      
4813         }                                                                                                
4814     }                                                                                                    
4815                                                                                                          
4816     /**                                                                                                  
4817      * Some shortcuts were updated in the background.                                                    
4818      *                                                                                                   
4819      * Implementation of the method from LauncherModel.Callbacks.                                        
4820      */                                                                                                  
4821     public void bindShortcutsUpdated(final ArrayList<ShortcutInfo> shortcuts) {                          
4822         Runnable r = new Runnable() {                                                                    
4823             public void run() {                                                                          
4824                 bindShortcutsUpdated(shortcuts);                                                         
4825             }                                                                                            
4826         };                                                                                               
4827         if (waitUntilResume(r)) {                                                                        
4828             return;                                                                                      
4829         }                                                                                                
4830                                                                                                          
4831         if (mWorkspace != null) {                                                                        
4832             mWorkspace.updateShortcuts(shortcuts);                                                       
4833         }                                                                                                
4834     }                                                                                                    
4835                                                                                                          
4836     /**                                                                                                  
4837      * Packages were restored                                                                            
4838      */                                                                                                  
4839     public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                        
4840         Runnable r = new Runnable() {                                                                    
4841             public void run() {                                                                          
4842                 bindAppsRestored(apps);                                                                  
4843             }                                                                                            
4844         };                                                                                               
4845         if (waitUntilResume(r)) {                                                                        
4846             return;                                                                                      
4847         }                                                                                                
4848                                                                                                          
4849         if (mWorkspace != null) {                                                                        
4850             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4851         }                                                                                                
4852     }                                                                                                    
4853                                                                                                          
4854     /**                                                                                                  
4855      * Update the state of a package, typically related to install state.                                
4856      *                                                                                                   
4857      * Implementation of the method from LauncherModel.Callbacks.                                        
4858      */                                                                                                  
4859     @Override                                                                                            
4860     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4861         if (mWorkspace != null) {                                                                        
4862             mWorkspace.updatePackageState(installInfo);                                                  
4863         }                                                                                                
4864     }                                                                                                    
4865                                                                                                          
4866     /**                                                                                                  
4867      * Update the label and icon of all the icons in a package                                           
4868      *                                                                                                   
4869      * Implementation of the method from LauncherModel.Callbacks.                                        
4870      */                                                                                                  
4871     @Override                                                                                            
4872     public void updatePackageBadge(String packageName) {                                                 
4873         if (mWorkspace != null) {                                                                        
4874             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4875         }                                                                                                
4876     }                                                                                                    
4877                                                                                                          
4878     /**                                                                                                  
4879      * A package was uninstalled.  We take both the super set of packageNames                            
4880      * in addition to specific applications to remove, the reason being that                             
4881      * this can be called when a package is updated as well.  In that scenario,                          
4882      * we only remove specific components from the workspace, where as                                   
4883      * package-removal should clear all items by package name.                                           
4884      *                                                                                                   
4885      * @param reason                                                                                     
4886      * 		if non-zero, the icons are not permanently removed, rather marked as disabled.                  
4887      * 		Implementation of the method from LauncherModel.Callbacks.                                      
4888      */                                                                                                  
4889     @Override                                                                                            
4890     public void bindComponentsRemoved(final ArrayList<String> packageNames, final ArrayList<AppInfo> appI🔵
4891         Runnable r = new Runnable() {                                                                    
4892             public void run() {                                                                          
4893                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4894             }                                                                                            
4895         };                                                                                               
4896         if (waitUntilResume(r)) {                                                                        
4897             return;                                                                                      
4898         }                                                                                                
4899         if (reason == 0) {                                                                               
4900             if (!packageNames.isEmpty()) {                                                               
4901                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4902             }                                                                                            
4903             if (!appInfos.isEmpty()) {                                                                   
4904                 mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                 
4905             }                                                                                            
4906         } else {                                                                                         
4907             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4908         }                                                                                                
4909         // Notify the drag controller                                                                    
4910         mDragController.onAppsRemoved(packageNames, appInfos);                                           
4911         // Update AllApps                                                                                
4912         if ((!LauncherAppState.isDisableAllApps()) && (mAppsCustomizeContent != null)) {                 
4913             mAppsCustomizeContent.removeApps(appInfos);                                                  
4914         }                                                                                                
4915     }                                                                                                    
4916                                                                                                          
4917     /**                                                                                                  
4918      * A number of packages were updated.                                                                
4919      */                                                                                                  
4920     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4921                                                                                                          
4922     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4923             public void run() {                                                                          
4924                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4925                 mWidgetsAndShortcuts = null;                                                             
4926             }                                                                                            
4927         };                                                                                               
4928                                                                                                          
4929     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4930         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4931             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4932             return;                                                                                      
4933         }                                                                                                
4934                                                                                                          
4935         // Update the widgets pane                                                                       
4936         if (mAppsCustomizeContent != null) {                                                             
4937             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4938         }                                                                                                
4939     }                                                                                                    
4940                                                                                                          
4941     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4942         final Display d = getWindowManager().getDefaultDisplay();                                        
4943         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4944         switch (d.getRotation()) {                                                                       
4945         case Surface.ROTATION_0:                                                                         
4946         case Surface.ROTATION_180:                                                                       
4947             // We are currently in the same basic orientation as the natural orientation                 
4948             naturalOri = configOri;                                                                      
4949             break;                                                                                       
4950         case Surface.ROTATION_90:                                                                        
4951         case Surface.ROTATION_270:                                                                       
4952             // We are currently in the other basic orientation to the natural orientation                
4953             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4954                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4955             break;                                                                                       
4956         }                                                                                                
4957                                                                                                          
4958         int[] oriMap = {                                                                                 
4959                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4960                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4961                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4962                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4963         };                                                                                               
4964         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4965         // is landscape.                                                                                 
4966         int indexOffset = 0;                                                                             
4967         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4968             indexOffset = 1;                                                                             
4969         }                                                                                                
4970         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4971     }                                                                                                    
4972                                                                                                          
4973     public boolean isRotationEnabled() {                                                                 
4974         boolean enableRotation = sForceEnableRotation ||                                                 
4975                 getResources().getBoolean(R.bool.allow_rotation);                                        
4976         return enableRotation;                                                                           
4977     }                                                                                                    
4978                                                                                                          
4979     public void lockScreenOrientation() {                                                                
4980         if (isRotationEnabled()) {                                                                       
4981             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                    
4982                     .getConfiguration().orientation));                                                   
4983         }                                                                                                
4984     }                                                                                                    
4985                                                                                                          
4986     public void unlockScreenOrientation(boolean immediate) {                                             
4987         if (isRotationEnabled()) {                                                                       
4988             if (immediate) {                                                                             
4989                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4990             } else {                                                                                     
4991                 mHandler.postDelayed(new Runnable() {                                                    
4992                     public void run() {                                                                  
4993                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4994                     }                                                                                    
4995                 }, mRestoreScreenOrientationDelay);                                                      
4996             }                                                                                            
4997         }                                                                                                
4998     }                                                                                                    
4999                                                                                                          
5000     /**                                                                                                  
5001      * Called when the SearchBar hint should be changed.                                                 
5002      *                                                                                                   
5003      * @param hint the hint to be displayed in the search bar.                                           
5004      */                                                                                                  
5005     protected void onSearchBarHintChanged(String hint) {                                                 
5006                                                                                                          
5007     }                                                                                                    
5008                                                                                                          
5009     protected boolean isLauncherPreinstalled() {                                                         
5010         PackageManager pm = getPackageManager();                                                         
5011         try {                                                                                            
5012             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
5013             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
5014                 return true;                                                                             
5015             } else {                                                                                     
5016                 return false;                                                                            
5017             }                                                                                            
5018         } catch (NameNotFoundException e) {                                                              
5019             e.printStackTrace();                                                                         
5020             return false;                                                                                
5021         }                                                                                                
5022     }                                                                                                    
5023                                                                                                          
5024     /**                                                                                                  
5025      * This method indicates whether or not we should suggest default wallpaper dimensions               
5026      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
5027      */                                                                                                  
5028     protected boolean overrideWallpaperDimensions() {                                                    
5029         return true;                                                                                     
5030     }                                                                                                    
5031                                                                                                          
5032     /**                                                                                                  
5033      * To be overridden by subclasses to indicate that there is an activity to launch                    
5034      * before showing the standard launcher experience.                                                  
5035      */                                                                                                  
5036     protected boolean hasFirstRunActivity() {                                                            
5037         return false;                                                                                    
5038     }                                                                                                    
5039                                                                                                          
5040     /**                                                                                                  
5041      * To be overridden by subclasses to launch any first run activity                                   
5042      */                                                                                                  
5043     protected Intent getFirstRunActivity() {                                                             
5044         return null;                                                                                     
5045     }                                                                                                    
5046                                                                                                          
5047     private boolean shouldRunFirstRunActivity() {                                                        
5048         return !ActivityManager.isRunningInTestHarness() &&                                              
5049                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
5050     }                                                                                                    
5051                                                                                                          
5052     protected boolean hasRunFirstRunActivity() {                                                         
5053         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
5054     }                                                                                                    
5055                                                                                                          
5056     public boolean showFirstRunActivity() {                                                              
5057         if (shouldRunFirstRunActivity() &&                                                               
5058                 hasFirstRunActivity()) {                                                                 
5059             Intent firstRunIntent = getFirstRunActivity();                                               
5060             if (firstRunIntent != null) {                                                                
5061                 startActivity(firstRunIntent);                                                           
5062                 markFirstRunActivityShown();                                                             
5063                 return true;                                                                             
5064             }                                                                                            
5065         }                                                                                                
5066         return false;                                                                                    
5067     }                                                                                                    
5068                                                                                                          
5069     private void markFirstRunActivityShown() {                                                           
5070         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5071         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
5072         editor.apply();                                                                                  
5073     }                                                                                                    
5074                                                                                                          
5075     /**                                                                                                  
5076      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
5077      * screen that must be displayed and dismissed.                                                      
5078      */                                                                                                  
5079     protected boolean hasDismissableIntroScreen() {                                                      
5080         return false;                                                                                    
5081     }                                                                                                    
5082                                                                                                          
5083     /**                                                                                                  
5084      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
5085      */                                                                                                  
5086     protected View getIntroScreen() {                                                                    
5087         return null;                                                                                     
5088     }                                                                                                    
5089                                                                                                          
5090     /**                                                                                                  
5091      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
5092      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
5093      */                                                                                                  
5094     private boolean shouldShowIntroScreen() {                                                            
5095         return hasDismissableIntroScreen() &&                                                            
5096                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
5097     }                                                                                                    
5098                                                                                                          
5099     protected void showIntroScreen() {                                                                   
5100         View introScreen = getIntroScreen();                                                             
5101         changeWallpaperVisiblity(false);                                                                 
5102         if (introScreen != null) {                                                                       
5103             mDragLayer.showOverlayView(introScreen);                                                     
5104         }                                                                                                
5105     }                                                                                                    
5106                                                                                                          
5107     public void dismissIntroScreen() {                                                                   
5108         markIntroScreenDismissed();                                                                      
5109         if (showFirstRunActivity()) {                                                                    
5110             // We delay hiding the intro view until the first run activity is showing. This              
5111             // avoids a blip.                                                                            
5112             mWorkspace.postDelayed(new Runnable() {                                                      
5113                 @Override                                                                                
5114                 public void run() {                                                                      
5115                     mDragLayer.dismissOverlayView();                                                     
5116                     showFirstRunClings();                                                                
5117                 }                                                                                        
5118             }, ACTIVITY_START_DELAY);                                                                    
5119         } else {                                                                                         
5120             mDragLayer.dismissOverlayView();                                                             
5121             showFirstRunClings();                                                                        
5122         }                                                                                                
5123         changeWallpaperVisiblity(true);                                                                  
5124     }                                                                                                    
5125                                                                                                          
5126     private void markIntroScreenDismissed() {                                                            
5127         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5128         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
5129         editor.apply();                                                                                  
5130     }                                                                                                    
5131                                                                                                          
5132     private void showFirstRunClings() {                                                                  
5133         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
5134         // on the device, then we always show the first run cling experience (or if there is no          
5135         // launcher2). Otherwise, we prompt the user upon started for migration                          
5136         LauncherClings launcherClings = new LauncherClings(this);                                        
5137         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
5138             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
5139                 launcherClings.showMigrationCling();                                                     
5140             } else {                                                                                     
5141                 launcherClings.showLongPressCling(true);                                                 
5142             }                                                                                            
5143         }                                                                                                
5144     }                                                                                                    
5145                                                                                                          
5146     void showWorkspaceSearchAndHotseat() {                                                               
5147         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
5148         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
5149         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
5150         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
5151     }                                                                                                    
5152                                                                                                          
5153     void hideWorkspaceSearchAndHotseat() {                                                               
5154         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
5155         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
5156         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
5157         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
5158     }                                                                                                    
5159                                                                                                          
5160     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
5161         // Called from search suggestion, not supported in other profiles.                               
5162         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
5163         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
5164         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
5165                 myUser);                                                                                 
5166         if (activityInfo == null) {                                                                      
5167             return null;                                                                                 
5168         }                                                                                                
5169         return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                
5170     }                                                                                                    
5171                                                                                                          
5172     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5173             Bitmap icon) {                                                                               
5174         // Called from search suggestion, not supported in other profiles.                               
5175         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
5176                 UserHandleCompat.myUserHandle());                                                        
5177     }                                                                                                    
5178                                                                                                          
5179     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5180             Bitmap icon, UserHandleCompat user) {                                                        
5181         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
5182         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
5183         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
5184     }                                                                                                    
5185                                                                                                          
5186     protected void moveWorkspaceToDefaultScreen() {                                                      
5187         mWorkspace.moveToDefaultScreen(false);                                                           
5188     }                                                                                                    
5189                                                                                                          
5190     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
5191         dragView.setTag(dragInfo);                                                                       
5192         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
5193         mWorkspace.beginExternalDragShared(dragView, source);                                            
5194     }                                                                                                    
5195                                                                                                          
5196     @Override                                                                                            
5197     public void onPageSwitch(View newPage, int newPageIndex) {                                           
5198     }                                                                                                    
5199                                                                                                          
5200     /**                                                                                                  
5201      * Prints out out state for debugging.                                                               
5202      */                                                                                                  
5203     public void dumpState() {                                                                            
5204         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
5205         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
5206         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
5207         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
5208         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
5209         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
5210         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
5211         mModel.dumpState();                                                                              
5212                                                                                                          
5213         if (mAppsCustomizeContent != null) {                                                             
5214             mAppsCustomizeContent.dumpState();                                                           
5215         }                                                                                                
5216         Log.d(TAG, "END launcher3 dump state");                                                          
5217     }                                                                                                    
5218                                                                                                          
5219     @Override                                                                                            
5220     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
5221         super.dump(prefix, fd, writer, args);                                                            
5222         synchronized (sDumpLogs) {                                                                       
5223             writer.println(" ");                                                                         
5224             writer.println("Debug logs: ");                                                              
5225             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
5226                 writer.println("  " + sDumpLogs.get(i));                                                 
5227             }                                                                                            
5228         }                                                                                                
5229     }                                                                                                    
5230                                                                                                          
5231     public static void dumpDebugLogsToConsole() {                                                        
5232         if (DEBUG_DUMP_LOG) {                                                                            
5233             synchronized (sDumpLogs) {                                                                   
5234                 Log.d(TAG, "");                                                                          
5235                 Log.d(TAG, "*********************");                                                     
5236                 Log.d(TAG, "Launcher debug logs: ");                                                     
5237                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
5238                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
5239                 }                                                                                        
5240                 Log.d(TAG, "*********************");                                                     
5241                 Log.d(TAG, "");                                                                          
5242             }                                                                                            
5243         }                                                                                                
5244     }                                                                                                    
5245                                                                                                          
5246     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
5247         addDumpLog(tag, log, null, debugLog);                                                            
5248     }                                                                                                    
5249                                                                                                          
5250     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
5251         if (debugLog) {                                                                                  
5252             if (e != null) {                                                                             
5253                 Log.d(tag, log, e);                                                                      
5254             } else {                                                                                     
5255                 Log.d(tag, log);                                                                         
5256             }                                                                                            
5257         }                                                                                                
5258         if (DEBUG_DUMP_LOG) {                                                                            
5259             sDateStamp.setTime(System.currentTimeMillis());                                              
5260             synchronized (sDumpLogs) {                                                                   
5261                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
5262                     + (e == null ? "" : (", Exception: " + e)));                                         
5263             }                                                                                            
5264         }                                                                                                
5265     }                                                                                                    
5266                                                                                                          
5267     public void dumpLogsToLocalData() {                                                                  
5268         if (DEBUG_DUMP_LOG) {                                                                            
5269             new AsyncTask<Void, Void, Void>() {                                                          
5270                 public Void doInBackground(Void ... args) {                                              
5271                     boolean success = false;                                                             
5272                     sDateStamp.setTime(sRunStart);                                                       
5273                     String FILENAME = sDateStamp.getMonth() + "-"                                        
5274                             + sDateStamp.getDay() + "_"                                                  
5275                             + sDateStamp.getHours() + "-"                                                
5276                             + sDateStamp.getMinutes() + "_"                                              
5277                             + sDateStamp.getSeconds() + ".txt";                                          
5278                                                                                                          
5279                     FileOutputStream fos = null;                                                         
5280                     File outFile = null;                                                                 
5281                     try {                                                                                
5282                         outFile = new File(getFilesDir(), FILENAME);                                     
5283                         outFile.createNewFile();                                                         
5284                         fos = new FileOutputStream(outFile);                                             
5285                     } catch (Exception e) {                                                              
5286                         e.printStackTrace();                                                             
5287                     }                                                                                    
5288                     if (fos != null) {                                                                   
5289                         PrintWriter writer = new PrintWriter(fos);                                       
5290                                                                                                          
5291                         writer.println(" ");                                                             
5292                         writer.println("Debug logs: ");                                                  
5293                         synchronized (sDumpLogs) {                                                       
5294                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
5295                                 writer.println("  " + sDumpLogs.get(i));                                 
5296                             }                                                                            
5297                         }                                                                                
5298                         writer.close();                                                                  
5299                     }                                                                                    
5300                     try {                                                                                
5301                         if (fos != null) {                                                               
5302                             fos.close();                                                                 
5303                             success = true;                                                              
5304                         }                                                                                
5305                     } catch (IOException e) {                                                            
5306                         e.printStackTrace();                                                             
5307                     }                                                                                    
5308                     return null;                                                                         
5309                 }                                                                                        
5310             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
5311         }                                                                                                
5312     }                                                                                                    
5313 }                                                                                                        
5314                                                                                                          
5315 interface LauncherTransitionable {                                                                       
5316     public abstract View getContent();                                                                   
5317                                                                                                          
5318     public abstract void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace); 
5319                                                                                                          
5320     public abstract void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);   
5321                                                                                                          
5322     public abstract void onLauncherTransitionStep(Launcher l, float t);                                  
5323                                                                                                          
5324     public abstract void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);     
5325 }                                                                                                        
ours vs. base theirs vs. base
   1                                                                                                                    
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25  import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.SharedPreferences;                                                                         
  46  import android.content.pm.ActivityInfo;                                                                           
  47  import android.content.pm.ApplicationInfo;                                                                        
  48  import android.content.pm.PackageManager;                                                                         
  49  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  50  import android.content.res.Configuration;                                                                         
  51  import android.content.res.Resources;                                                                             
  52  import android.database.ContentObserver;                                                                          
  53  import android.graphics.Bitmap;                                                                                   
  54  import android.graphics.Canvas;                                                                                   
  55  import android.graphics.Color;                                                                                    
  56  import android.graphics.Point;                                                                                    
  57  import android.graphics.PorterDuff;                                                                               
  58  import android.graphics.Rect;                                                                                     
  59  import android.graphics.drawable.Drawable;                                                                        
  60  import android.net.Uri;                                                                                           
  61  import android.os.AsyncTask;                                                                                      
  62  import android.os.Build;                                                                                          
  63  import android.os.Bundle;                                                                                         
  64  import android.os.Environment;                                                                                    
  65  import android.os.Handler;                                                                                        
  66  import android.os.Message;                                                                                        
  67  import android.os.StrictMode;                                                                                     
  68  import android.os.SystemClock;                                                                                    
  69  import android.speech.RecognizerIntent;                                                                           
  70  import android.text.Selection;                                                                                    
  71  import android.text.SpannableStringBuilder;                                                                       
  72  import android.text.TextUtils;                                                                                    
  73  import android.text.method.TextKeyListener;                                                                       
  74  import android.util.DisplayMetrics;                                                                               
  75  import android.util.Log;                                                                                          
  76 -import android.view.ContextThemeWrapper;                                                                          
  77  import android.view.Display;                                                                                      
  78  import android.view.Gravity;                                                                                      
  79  import android.view.HapticFeedbackConstants;                                                                      
  80  import android.view.KeyEvent;                                                                                     
  81  import android.view.LayoutInflater;                                                                               
  82  import android.view.Menu;                                                                                         
  83  import android.view.MotionEvent;                                                                                  
  84  import android.view.Surface;                                                                                      
  85  import android.view.View;                                                                                         
  86  import android.view.View.OnClickListener;                                                                         
  87  import android.view.View.OnLongClickListener;                                                                     
  88  import android.view.ViewAnimationUtils;                                                                           
  89  import android.view.ViewGroup;                                                                                    
  90  import android.view.ViewTreeObserver;                                                                             
  91 -import android.view.ViewTreeObserver.OnGlobalLayoutListener;                                                      
  92  import android.view.Window;                                                                                       
  93  import android.view.WindowManager;                                                                                
  94  import android.view.accessibility.AccessibilityEvent;                                                             
  95  import android.view.animation.AccelerateInterpolator;                                                             
  96  import android.view.animation.DecelerateInterpolator;                                                             
  97 -import android.view.animation.Interpolator;                                                                       
  98  import android.view.inputmethod.InputMethodManager;                                                               
  99  import android.widget.Advanceable;                                                                                
 100  import android.widget.FrameLayout;                                                                                
 101  import android.widget.ImageView;                                                                                  
 102  import android.widget.TextView;                                                                                   
 103  import android.widget.Toast;                                                                                      
 104                                                                                                                    
 105  import com.android.launcher3.DropTarget.DragObject;                                                               
 106  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 107  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 108  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 109  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 110  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 111  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 112  import com.android.launcher3.compat.UserHandleCompat;                                                             
 113  import com.android.launcher3.compat.UserManagerCompat;                                                            
 114                                                                                                                    
 115  import java.io.DataInputStream;                                                                                   
 116  import java.io.DataOutputStream;                                                                                  
 117  import java.io.File;                                                                                              
 118  import java.io.FileDescriptor;                                                                                    
 119  import java.io.FileNotFoundException;                                                                             
 120  import java.io.FileOutputStream;                                                                                  
 121  import java.io.IOException;                                                                                       
 122  import java.io.PrintWriter;                                                                                       
 123  import java.lang.reflect.Field;                                                                                   
 124  import java.lang.reflect.InvocationTargetException;                                                               
 125  import java.lang.reflect.Method;                                                                                  
 126  import java.text.DateFormat;                                                                                      
 127  import java.util.ArrayList;                                                                                       
 128  import java.util.Collection;                                                                                      
 129  import java.util.Date;                                                                                            
 130  import java.util.HashMap;                                                                                         
 131  import java.util.List;                                                                                            
 132  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 133                                                                                                                    
 134  /**                                                                                                               
 135   * Default launcher application.                                                                                  
 136   */                                                                                                               
 137  public class Launcher extends Activity                                                                            
 138          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 139                     View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     
 140      static final String TAG = "Launcher";                                                                         
 141      static final boolean LOGD = false;                                                                            
 142                                                                                                                    
 143      static final boolean PROFILE_STARTUP = false;                                                                 
 144      static final boolean DEBUG_WIDGETS = false;                                                                   
 145      static final boolean DEBUG_STRICT_MODE = false;                                                               
 146      static final boolean DEBUG_RESUME_TIME = false;                                                               
 147      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 148                                                                                                                    
 149      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 150                                                                                                                    
 151      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 152      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 153      private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 154      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 155      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 156                                                                                                                    
 157      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 158      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 159                                                                                                                    
 160      /**                                                                                                           
 161       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 162       * request codes used internally.                                                                             
 163       */                                                                                                           
 164      protected static final int REQUEST_LAST = 100;                                                                
 165                                                                                                                    
 166      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 167                                                                                                                    
 168      static final int SCREEN_COUNT = 5;                                                                            
 169      static final int DEFAULT_SCREEN = 2;                                                                          
 170                                                                                                                    
 171 -    private static final String PREFERENCES = "launcher.preferences";                                             
 172      // To turn on these properties, type                                                                          
 173      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 174      static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                                 
 175      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 176      static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 177                                                                                                                    
 178      // The Intent extra that defines whether to ignore the launch animation                                       
 179      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 180              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 181                                                                                                                    
 182      // Type: int                                                                                                  
 183      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 184      // Type: int                                                                                                  
 185      private static final String RUNTIME_STATE = "launcher.state";                                                 
 186      // Type: int                                                                                                  
 187      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 188      // Type: int                                                                                                  
 189      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 190      // Type: int                                                                                                  
 191      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 192      // Type: int                                                                                                  
 193      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 194      // Type: boolean                                                                                              
 195      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 196      // Type: long                                                                                                 
 197      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 198      // Type: int                                                                                                  
 199      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 200      // Type: int                                                                                                  
 201      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 202      // Type: parcelable                                                                                           
 203      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 204      // Type: parcelable                                                                                           
 205      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 206      // Type: int[]                                                                                                
 207      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 208                                                                                                                    
 209      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 210      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 211                                                                                                                    
 212      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 213      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 214              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 215                                                                                                                    
 216      private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";                 
 217      private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                               
 218              "com.android.launcher.toolbar_search_icon";                                                           
 219      private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                         
 220              "com.android.launcher.toolbar_voice_search_icon";                                                     
 221                                                                                                                    
 222      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 223      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 224                                                                                                                    
 225      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 226                                                                                                                    
 227      /** The different states that Launcher can be in. */                                                          
 228      private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 229      private State mState = State.WORKSPACE;                                                                       
 230      private AnimatorSet mStateAnimation;                                                                          
 231                                                                                                                    
 232      private boolean mIsSafeModeEnabled;                                                                           
 233                                                                                                                    
 234      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 235      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 236      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 237      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 238                                                                                                                    
 239      private static final Object sLock = new Object();                                                             
 240      private static int sScreen = DEFAULT_SCREEN;                                                                  
 241                                                                                                                    
 242      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 243      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 244                                                                                                                    
 245      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 246      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 247      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 248      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 249      private static final int SINGLE_FRAME_DELAY = 16;                                                             
 250                                                                                                                    
 251      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 252              = new CloseSystemDialogsIntentReceiver();                                                             
 253      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 254                                                                                                                    
 255      private LayoutInflater mInflater;                                                                             
 256                                                                                                                    
 257      private Workspace mWorkspace;                                                                                 
 258      private View mLauncherView;                                                                                   
 259      private View mPageIndicators;                                                                                 
 260      private DragLayer mDragLayer;                                                                                 
 261      private DragController mDragController;                                                                       
 262      private View mWeightWatcher;                                                                                  
 263                                                                                                                    
 264      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 265      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 266                                                                                                                    
 267      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 268      private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                          
 269      private int mPendingAddWidgetId = -1;                                                                         
 270                                                                                                                    
 271      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 272                                                                                                                    
 273      private FolderInfo mFolderInfo;                                                                               
 274                                                                                                                    
 275      private Hotseat mHotseat;                                                                                     
 276      private ViewGroup mOverviewPanel;                                                                             
 277                                                                                                                    
 278      private View mAllAppsButton;                                                                                  
 279                                                                                                                    
 280      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 281      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 282      private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 283      private boolean mAutoAdvanceRunning = false;                                                                  
 284      private View mQsb;                                                                                            
 285                                                                                                                    
 286      private Bundle mSavedState;                                                                                   
 287      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 288      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 289      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 290      private State mOnResumeState = State.NONE;                                                                    
 291                                                                                                                    
 292      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 293                                                                                                                    
 294      private boolean mWorkspaceLoading = true;                                                                     
 295                                                                                                                    
 296      private boolean mPaused = true;                                                                               
 297      private boolean mRestoring;                                                                                   
 298      private boolean mWaitingForResult;                                                                            
 299      private boolean mOnResumeNeedsLoad;                                                                           
 300                                                                                                                    
 301      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 302      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 303                                                                                                                    
 304      private Bundle mSavedInstanceState;                                                                           
 305                                                                                                                    
 306      private LauncherModel mModel;                                                                                 
 307      private IconCache mIconCache;                                                                                 
 308      private boolean mUserPresent = true;                                                                          
 309      private boolean mVisible = false;                                                                             
 310      private boolean mHasFocus = false;                                                                            
 311      private boolean mAttached = false;                                                                            
 312                                                                                                                    
 313      private static LocaleConfiguration sLocaleConfiguration = null;                                               
 314                                                                                                                    
 315      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 316                                                                                                                    
 317      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 318                                                                                                                    
 319      // Related to the auto-advancing of widgets                                                                   
 320      private final int ADVANCE_MSG = 1;                                                                            
 321      private final int mAdvanceInterval = 20000;                                                                   
 322      private final int mAdvanceStagger = 250;                                                                      
 323      private long mAutoAdvanceSentTime;                                                                            
 324      private long mAutoAdvanceTimeLeft = -1;                                                                       
 325      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 326          new HashMap<View, AppWidgetProviderInfo>();                                                               
 327                                                                                                                    
 328      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 329      // match the sensor state.                                                                                    
 330      private final int mRestoreScreenOrientationDelay = 500;                                                       
 331                                                                                                                    
 332      // External icons saved in case of resource changes, orientation, etc.                                        
 333      private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];                    
 334      private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];                     
 335                                                                                                                    
 336      private Drawable mWorkspaceBackgroundDrawable;                                                                
 337                                                                                                                    
 338      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 339      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 340                                                                                                                    
 341      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 342      static Date sDateStamp = new Date();                                                                          
 343      static DateFormat sDateFormat =                                                                               
 344              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 345      static long sRunStart = System.currentTimeMillis();                                                           
 346      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 347                                                                                                                    
 348      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 349      // it from the context.                                                                                       
 350      private SharedPreferences mSharedPrefs;                                                                       
 351                                                                                                                    
 352      private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 353                                                                                                                    
 354      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 355      // when we scroll to that page on resume.                                                                     
 356      private ImageView mFolderIconImageView;                                                                       
 357      private Bitmap mFolderIconBitmap;                                                                             
 358      private Canvas mFolderIconCanvas;                                                                             
 359      private Rect mRectForFolderAnimation = new Rect();                                                            
 360                                                                                                                    
 361      private BubbleTextView mWaitingForResume;                                                                     
 362                                                                                                                    
 363      private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 364          public void run() {                                                                                       
 365              if (mWorkspace != null) {                                                                             
 366                  mWorkspace.buildPageHardwareLayers();                                                             
 367              }                                                                                                     
 368          }                                                                                                         
 369      };                                                                                                            
 370                                                                                                                    
 371      private static PendingAddArguments sPendingAddItem;                                                           
 372                                                                                                                    
 373      public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);               
 374                                                                                                                    
 375      private static class PendingAddArguments {                                                                    
 376          int requestCode;                                                                                          
 377          Intent intent;                                                                                            
 378          long container;                                                                                           
 379          long screenId;                                                                                            
 380          int cellX;                                                                                                
 381          int cellY;                                                                                                
 382          int appWidgetId;                                                                                          
 383      }                                                                                                             
 384                                                                                                                    
 385      private Stats mStats;                                                                                         
 386                                                                                                                    
 387      FocusIndicatorView mFocusHandler;                                                                             
 388                                                                                                                    
 389      static boolean isPropertyEnabled(String propertyName) {                                                       
 390          return Log.isLoggable(propertyName, Log.VERBOSE);                                                         
 391      }                                                                                                             
 392                                                                                                                    
 393      @Override                                                                                                     
 394      protected void onCreate(Bundle savedInstanceState) {                                                          
 395          if (DEBUG_STRICT_MODE) {                                                                                  
 396              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 397                      .detectDiskReads()                                                                            
 398                      .detectDiskWrites()                                                                           
 399                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 400                      .penaltyLog()                                                                                 
 401                      .build());                                                                                    
 402              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 403                      .detectLeakedSqlLiteObjects()                                                                 
 404                      .detectLeakedClosableObjects()                                                                
 405                      .penaltyLog()                                                                                 
 406                      .penaltyDeath()                                                                               
 407                      .build());                                                                                    
 408          }                                                                                                         
 409                                                                                                                    
 410          super.onCreate(savedInstanceState);                                                                       
 411                                                                                                                    
 412          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 413          LauncherAppState app = LauncherAppState.getInstance();                                                    
 414          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 415          // Determine the dynamic grid properties                                                                  
 416          Point smallestSize = new Point();                                                                         
 417          Point largestSize = new Point();                                                                          
 418          Point realSize = new Point();                                                                             
 419          Display display = getWindowManager().getDefaultDisplay();                                                 
 420          display.getCurrentSizeRange(smallestSize, largestSize);                                                   
 421          display.getRealSize(realSize);                                                                            
 422          DisplayMetrics dm = new DisplayMetrics();                                                                 
 423          display.getMetrics(dm);                                                                                   
 424                                                                                                                    
 425          // Lazy-initialize the dynamic grid                                                                       
 426          DeviceProfile grid = app.initDynamicGrid(this,                                                            
 427                  Math.min(smallestSize.x, smallestSize.y),                                                         
 428                  Math.min(largestSize.x, largestSize.y),                                                           
 429                  realSize.x, realSize.y,                                                                           
 430                  dm.widthPixels, dm.heightPixels);                                                                 
 431                                                                                                                    
 432          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 433          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 434                  Context.MODE_PRIVATE);                                                                            
 435          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 436          mModel = app.setLauncher(this);                                                                           
 437          mIconCache = app.getIconCache();                                                                          
 438          mIconCache.flushInvalidIcons(grid);                                                                       
 439          mDragController = new DragController(this);                                                               
 440          mInflater = getLayoutInflater();                                                                          
 441                                                                                                                    
 442          mStats = new Stats(this);                                                                                 
 443                                                                                                                    
 444          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 445                                                                                                                    
 446          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 447          mAppWidgetHost.startListening();                                                                          
 448                                                                                                                    
 449          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 450          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 451          // LauncherModel load.                                                                                    
 452          mPaused = false;                                                                                          
 453                                                                                                                    
 454          if (PROFILE_STARTUP) {                                                                                    
 455              android.os.Debug.startMethodTracing(                                                                  
 456                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 457          }                                                                                                         
 458                                                                                                                    
 459          checkForLocaleChange();                                                                                   
 460          setContentView(R.layout.launcher);                                                                        
 461                                                                                                                    
 462          setupViews();                                                                                             
 463          grid.layout(this);                                                                                        
 464                                                                                                                    
 465          registerContentObservers();                                                                               
 466                                                                                                                    
 467          lockAllApps();                                                                                            
 468                                                                                                                    
 469          mSavedState = savedInstanceState;                                                                         
 470          restoreState(mSavedState);                                                                                
 471                                                                                                                    
 472          if (PROFILE_STARTUP) {                                                                                    
 473              android.os.Debug.stopMethodTracing();                                                                 
 474          }                                                                                                         
 475                                                                                                                    
 476          if (!mRestoring) {                                                                                        
 477              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 478                  // If the user leaves launcher, then we should just load items asynchronously when                
 479                  // they return.                                                                                   
 480                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 481              } else {                                                                                              
 482                  // We only load the page synchronously if the user rotates (or triggers a                         
 483                  // configuration change) while launcher is in the foreground                                      
 484                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 485              }                                                                                                     
 486          }                                                                                                         
 487                                                                                                                    
 488          // For handling default keys                                                                              
 489          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 490          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 491                                                                                                                    
 492          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 493          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 494                                                                                                                    
 495          updateGlobalIcons();                                                                                      
 496                                                                                                                    
 497          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 498          unlockScreenOrientation(true);                                                                            
 499                                                                                                                    
 500          if (shouldShowIntroScreen()) {                                                                            
 501              showIntroScreen();                                                                                    
 502          } else {                                                                                                  
 503              showFirstRunActivity();                                                                               
 504              showFirstRunClings();                                                                                 
 505          }                                                                                                         
 506      }                                                                                                             
 507                                                                                                                    
 508      @Override                                                                                                     
 509      public void onLauncherProviderChange() { }                                                                    
 510                                                                                                                    
 511      /** To be overriden by subclasses to hint to Launcher that we have custom content */                          
 512      protected boolean hasCustomContentToLeft() {                                                                  
 513          return false;                                                                                             
 514      }                                                                                                             
 515                                                                                                                    
 516      /**                                                                                                           
 517       * To be overridden by subclasses to populate the custom content container and call                           
 518       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 519       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 520       */                                                                                                           
 521      protected void populateCustomContentContainer() {                                                             
 522      }                                                                                                             
 523                                                                                                                    
 524      /**                                                                                                           
 525       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 526       * ensure the custom content page is added or removed if necessary.                                           
 527       */                                                                                                           
 528      protected void invalidateHasCustomContentToLeft() {                                                           
 529          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 530              // Not bound yet, wait for bindScreens to be called.                                                  
 531              return;                                                                                               
 532          }                                                                                                         
 533                                                                                                                    
 534          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 535              // Create the custom content page and call the subclass to populate it.                               
 536              mWorkspace.createCustomContentContainer();                                                            
 537              populateCustomContentContainer();                                                                     
 538          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 539              mWorkspace.removeCustomContentPage();                                                                 
 540          }                                                                                                         
 541      }                                                                                                             
 542                                                                                                                    
 543      private void updateGlobalIcons() {                                                                            
 544          boolean searchVisible = false;                                                                            
 545          boolean voiceVisible = false;                                                                             
 546          // If we have a saved version of these external icons, we load them up immediately                        
 547          int coi = getCurrentOrientationIndexForGlobalIcons();                                                     
 548          if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                                    
 549              searchVisible = updateGlobalSearchIcon();                                                             
 550              voiceVisible = updateVoiceSearchIcon(searchVisible);                                                  
 551          }                                                                                                         
 552          if (sGlobalSearchIcon[coi] != null) {                                                                     
 553               updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                                      
 554               searchVisible = true;                                                                                
 555          }                                                                                                         
 556          if (sVoiceSearchIcon[coi] != null) {                                                                      
 557              updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                         
 558              voiceVisible = true;                                                                                  
 559          }                                                                                                         
 560          if (mSearchDropTargetBar != null) {                                                                       
 561              mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                            
 562          }                                                                                                         
 563      }                                                                                                             
 564                                                                                                                    
 565      private void checkForLocaleChange() {                                                                         
 566          if (sLocaleConfiguration == null) {                                                                       
 567              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 568                  @Override                                                                                         
 569                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 570                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 571                      readConfiguration(Launcher.this, localeConfiguration);                                        
 572                      return localeConfiguration;                                                                   
 573                  }                                                                                                 
 574                                                                                                                    
 575                  @Override                                                                                         
 576                  protected void onPostExecute(LocaleConfiguration result) {                                        
 577                      sLocaleConfiguration = result;                                                                
 578                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 579                  }                                                                                                 
 580              }.execute();                                                                                          
 581              return;                                                                                               
 582          }                                                                                                         
 583                                                                                                                    
 584          final Configuration configuration = getResources().getConfiguration();                                    
 585                                                                                                                    
 586          final String previousLocale = sLocaleConfiguration.locale;                                                
 587          final String locale = configuration.locale.toString();                                                    
 588                                                                                                                    
 589          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 590          final int mcc = configuration.mcc;                                                                        
 591                                                                                                                    
 592          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 593          final int mnc = configuration.mnc;                                                                        
 594                                                                                                                    
 595          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 596                                                                                                                    
 597          if (localeChanged) {                                                                                      
 598              sLocaleConfiguration.locale = locale;                                                                 
 599              sLocaleConfiguration.mcc = mcc;                                                                       
 600              sLocaleConfiguration.mnc = mnc;                                                                       
 601                                                                                                                    
 602              mIconCache.flush();                                                                                   
 603                                                                                                                    
 604              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 605              new AsyncTask<Void, Void, Void>() {                                                                   
 606                  public Void doInBackground(Void ... args) {                                                       
 607                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 608                      return null;                                                                                  
 609                  }                                                                                                 
 610              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 611          }                                                                                                         
 612      }                                                                                                             
 613                                                                                                                    
 614      private static class LocaleConfiguration {                                                                    
 615          public String locale;                                                                                     
 616          public int mcc = -1;                                                                                      
 617          public int mnc = -1;                                                                                      
 618      }                                                                                                             
 619                                                                                                                    
 620      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 621          DataInputStream in = null;                                                                                
 622          try {                                                                                                     
 623 -            in = new DataInputStream(context.openFileInput(PREFERENCES));                                         
 624 +            in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFS));                        
 625              configuration.locale = in.readUTF();                                                                  
 626              configuration.mcc = in.readInt();                                                                     
 627              configuration.mnc = in.readInt();                                                                     
 628          } catch (FileNotFoundException e) {                                                                       
 629              // Ignore                                                                                             
 630          } catch (IOException e) {                                                                                 
 631              // Ignore                                                                                             
 632          } finally {                                                                                               
 633              if (in != null) {                                                                                     
 634                  try {                                                                                             
 635                      in.close();                                                                                   
 636                  } catch (IOException e) {                                                                         
 637                      // Ignore                                                                                     
 638                  }                                                                                                 
 639              }                                                                                                     
 640          }                                                                                                         
 641      }                                                                                                             
 642                                                                                                                    
 643      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 644          DataOutputStream out = null;                                                                              
 645          try {                                                                                                     
 646 -            out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));                        
 647 +            out = new DataOutputStream(context.openFileOutput(                                                    
 648 +                    LauncherFiles.LAUNCHER_PREFS, MODE_PRIVATE));                                                 
 649              out.writeUTF(configuration.locale);                                                                   
 650              out.writeInt(configuration.mcc);                                                                      
 651              out.writeInt(configuration.mnc);                                                                      
 652              out.flush();                                                                                          
 653          } catch (FileNotFoundException e) {                                                                       
 654              // Ignore                                                                                             
 655          } catch (IOException e) {                                                                                 
 656              //noinspection ResultOfMethodCallIgnored                                                              
 657 -            context.getFileStreamPath(PREFERENCES).delete();                                                      
 658 +            context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFS).delete();                                     
 659          } finally {                                                                                               
 660              if (out != null) {                                                                                    
 661                  try {                                                                                             
 662                      out.close();                                                                                  
 663                  } catch (IOException e) {                                                                         
 664                      // Ignore                                                                                     
 665                  }                                                                                                 
 666              }                                                                                                     
 667          }                                                                                                         
 668      }                                                                                                             
 669                                                                                                                    
 670      public Stats getStats() {                                                                                     
 671          return mStats;                                                                                            
 672      }                                                                                                             
 673                                                                                                                    
 674      public LayoutInflater getInflater() {                                                                         
 675          return mInflater;                                                                                         
 676      }                                                                                                             
 677                                                                                                                    
 678      boolean isDraggingEnabled() {                                                                                 
 679          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 680          // that is subsequently removed from the workspace in startBinding().                                     
 681          return !mModel.isLoadingWorkspace();                                                                      
 682      }                                                                                                             
 683                                                                                                                    
 684      static int getScreen() {                                                                                      
 685          synchronized (sLock) {                                                                                    
 686              return sScreen;                                                                                       
 687          }                                                                                                         
 688      }                                                                                                             
 689                                                                                                                    
 690      static void setScreen(int screen) {                                                                           
 691          synchronized (sLock) {                                                                                    
 692              sScreen = screen;                                                                                     
 693          }                                                                                                         
 694      }                                                                                                             
 695                                                                                                                    
 696      public static int generateViewId() {                                                                          
 697          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 698              return View.generateViewId();                                                                         
 699          } else {                                                                                                  
 700              // View.generateViewId() is not available. The following fallback logic is a copy                     
 701              // of its implementation.                                                                             
 702              for (;;) {                                                                                            
 703                  final int result = sNextGeneratedId.get();                                                        
 704                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 705                  int newValue = result + 1;                                                                        
 706                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 707                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 708                      return result;                                                                                
 709                  }                                                                                                 
 710              }                                                                                                     
 711          }                                                                                                         
 712      }                                                                                                             
 713                                                                                                                    
 714      public int getViewIdForItem(ItemInfo info) {                                                                  
 715          // This cast is safe given the > 2B range for int.                                                        
 716          int itemId = (int) info.id;                                                                               
 717          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 718              return mItemIdToViewId.get(itemId);                                                                   
 719          }                                                                                                         
 720          int viewId = generateViewId();                                                                            
 721          mItemIdToViewId.put(itemId, viewId);                                                                      
 722          return viewId;                                                                                            
 723      }                                                                                                             
 724                                                                                                                    
 725      /**                                                                                                           
 726       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 727       * a configuration step, this allows the proper animations to run after other transitions.                    
 728       */                                                                                                           
 729      private long completeAdd(PendingAddArguments args) {                                                          
 730          long screenId = args.screenId;                                                                            
 731          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 732              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 733              // that the drop page actually exists.                                                                
 734              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 735          }                                                                                                         
 736                                                                                                                    
 737          switch (args.requestCode) {                                                                               
 738              case REQUEST_CREATE_SHORTCUT:                                                                         
 739                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 740                          args.cellY);                                                                              
 741                  break;                                                                                            
 742              case REQUEST_CREATE_APPWIDGET:                                                                        
 743                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 744                  break;                                                                                            
 745              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 746                  completeRestoreAppWidget(args.appWidgetId);                                                       
 747                  break;                                                                                            
 748          }                                                                                                         
 749          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 750          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 751          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 752          resetAddInfo();                                                                                           
 753          return screenId;                                                                                          
 754      }                                                                                                             
 755                                                                                                                    
 756      @Override                                                                                                     
 757      protected void onActivityResult(                                                                              
 758              final int requestCode, final int resultCode, final Intent data) {                                     
 759          // Reset the startActivity waiting flag                                                                   
 760          setWaitingForResult(false);                                                                               
 761          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 762          mPendingAddWidgetId = -1;                                                                                 
 763                                                                                                                    
 764          Runnable exitSpringLoaded = new Runnable() {                                                              
 765              @Override                                                                                             
 766              public void run() {                                                                                   
 767                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 768                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 769              }                                                                                                     
 770          };                                                                                                        
 771                                                                                                                    
 772          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 773              final int appWidgetId = data != null ?                                                                
 774                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 775              if (resultCode == RESULT_CANCELED) {                                                                  
 776                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 777                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 778                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 779              } else if (resultCode == RESULT_OK) {                                                                 
 780                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 781                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 782              }                                                                                                     
 783              return;                                                                                               
 784          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 785              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 786                  mWorkspace.exitOverviewMode(false);                                                               
 787              }                                                                                                     
 788              return;                                                                                               
 789          }                                                                                                         
 790                                                                                                                    
 791          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 792                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 793                                                                                                                    
 794          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 795          // We have special handling for widgets                                                                   
 796          if (isWidgetDrop) {                                                                                       
 797              final int appWidgetId;                                                                                
 798              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 799                      : -1;                                                                                         
 800              if (widgetId < 0) {                                                                                   
 801                  appWidgetId = pendingAddWidgetId;                                                                 
 802              } else {                                                                                              
 803                  appWidgetId = widgetId;                                                                           
 804              }                                                                                                     
 805                                                                                                                    
 806              final int result;                                                                                     
 807              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 808                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 809                          "returned from the widget configuration activity.");                                      
 810                  result = RESULT_CANCELED;                                                                         
 811                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 812                  final Runnable onComplete = new Runnable() {                                                      
 813                      @Override                                                                                     
 814                      public void run() {                                                                           
 815                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 816                      }                                                                                             
 817                  };                                                                                                
 818                  if (workspaceLocked) {                                                                            
 819                      // No need to remove the empty screen if we're mid-binding, as the                            
 820                      // the bind will not add the empty screen.                                                    
 821                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 822                  } else {                                                                                          
 823                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 824                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 825                  }                                                                                                 
 826              } else {                                                                                              
 827                  if (!workspaceLocked) {                                                                           
 828                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 829                          // When the screen id represents an actual screen (as opposed to a rank)                  
 830                          // we make sure that the drop page actually exists.                                       
 831                          mPendingAddInfo.screenId =                                                                
 832                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 833                      }                                                                                             
 834                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 835                                                                                                                    
 836                      dropLayout.setDropPending(true);                                                              
 837                      final Runnable onComplete = new Runnable() {                                                  
 838                          @Override                                                                                 
 839                          public void run() {                                                                       
 840                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 841                              dropLayout.setDropPending(false);                                                     
 842                          }                                                                                         
 843                      };                                                                                            
 844                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 845                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 846                  } else {                                                                                          
 847                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 848                              mPendingAddInfo);                                                                     
 849                      sPendingAddItem = args;                                                                       
 850                  }                                                                                                 
 851              }                                                                                                     
 852              return;                                                                                               
 853          }                                                                                                         
 854                                                                                                                    
 855          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 856              if (resultCode == RESULT_OK) {                                                                        
 857                  // Update the widget view.                                                                        
 858                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 859                          pendingAddWidgetId, mPendingAddInfo);                                                     
 860                  if (workspaceLocked) {                                                                            
 861                      sPendingAddItem = args;                                                                       
 862                  } else {                                                                                          
 863                      completeAdd(args);                                                                            
 864                  }                                                                                                 
 865              }                                                                                                     
 866              // Leave the widget in the pending state if the user canceled the configure.                          
 867              return;                                                                                               
 868          }                                                                                                         
 869                                                                                                                    
 870          // The pattern used here is that a user PICKs a specific application,                                     
 871          // which, depending on the target, might need to CREATE the actual target.                                
 872                                                                                                                    
 873          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 874          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 875          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 876              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 877                      mPendingAddInfo);                                                                             
 878              if (isWorkspaceLocked()) {                                                                            
 879                  sPendingAddItem = args;                                                                           
 880              } else {                                                                                              
 881                  completeAdd(args);                                                                                
 882                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 883                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 884              }                                                                                                     
 885          } else if (resultCode == RESULT_CANCELED) {                                                               
 886              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 887                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 888          }                                                                                                         
 889          mDragLayer.clearAnimatedView();                                                                           
 890      }                                                                                                             
 891                                                                                                                    
 892      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 893              appWidgetId, ItemInfo info) {                                                                         
 894          PendingAddArguments args = new PendingAddArguments();                                                     
 895          args.requestCode = requestCode;                                                                           
 896          args.intent = data;                                                                                       
 897          args.container = info.container;                                                                          
 898          args.screenId = info.screenId;                                                                            
 899          args.cellX = info.cellX;                                                                                  
 900          args.cellY = info.cellY;                                                                                  
 901          args.appWidgetId = appWidgetId;                                                                           
 902          return args;                                                                                              
 903      }                                                                                                             
 904                                                                                                                    
 905      /**                                                                                                           
 906       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 907       *                                                                                                            
 908       * @param screenId the screen id to check                                                                     
 909       * @return the new screen, or screenId if it exists                                                           
 910       */                                                                                                           
 911      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 912          CellLayout dropLayout =                                                                                   
 913                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 914          if (dropLayout == null) {                                                                                 
 915              // it's possible that the add screen was removed because it was                                       
 916              // empty and a re-bind occurred                                                                       
 917              mWorkspace.addExtraEmptyScreen();                                                                     
 918              return mWorkspace.commitExtraEmptyScreen();                                                           
 919          } else {                                                                                                  
 920              return screenId;                                                                                      
 921          }                                                                                                         
 922      }                                                                                                             
 923                                                                                                                    
 924      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
 925          CellLayout cellLayout =                                                                                   
 926                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 927          Runnable onCompleteRunnable = null;                                                                       
 928          int animationType = 0;                                                                                    
 929                                                                                                                    
 930          AppWidgetHostView boundWidget = null;                                                                     
 931          if (resultCode == RESULT_OK) {                                                                            
 932              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 933              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 934                      mPendingAddWidgetInfo);                                                                       
 935              boundWidget = layout;                                                                                 
 936              onCompleteRunnable = new Runnable() {                                                                 
 937                  @Override                                                                                         
 938                  public void run() {                                                                               
 939                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 940                              mPendingAddInfo.screenId, layout, null);                                              
 941                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 942                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 943                  }                                                                                                 
 944              };                                                                                                    
 945          } else if (resultCode == RESULT_CANCELED) {                                                               
 946              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
 947              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
 948          }                                                                                                         
 949          if (mDragLayer.getAnimatedView() != null) {                                                               
 950              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
 951                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
 952                      animationType, boundWidget, true);                                                            
 953          } else if (onCompleteRunnable != null) {                                                                  
 954              // The animated view may be null in the case of a rotation during widget configuration                
 955              onCompleteRunnable.run();                                                                             
 956          }                                                                                                         
 957      }                                                                                                             
 958                                                                                                                    
 959      @Override                                                                                                     
 960      protected void onStop() {                                                                                     
 961          super.onStop();                                                                                           
 962          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
 963      }                                                                                                             
 964                                                                                                                    
 965      @Override                                                                                                     
 966      protected void onStart() {                                                                                    
 967          super.onStart();                                                                                          
 968          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
 969      }                                                                                                             
 970                                                                                                                    
 971      @Override                                                                                                     
 972      protected void onResume() {                                                                                   
 973          long startTime = 0;                                                                                       
 974          if (DEBUG_RESUME_TIME) {                                                                                  
 975              startTime = System.currentTimeMillis();                                                               
 976              Log.v(TAG, "Launcher.onResume()");                                                                    
 977          }                                                                                                         
 978          super.onResume();                                                                                         
 979                                                                                                                    
 980          // Restore the previous launcher state                                                                    
 981          if (mOnResumeState == State.WORKSPACE) {                                                                  
 982              showWorkspace(false);                                                                                 
 983          } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
 984              showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    
 985          }                                                                                                         
 986          mOnResumeState = State.NONE;                                                                              
 987                                                                                                                    
 988          // Background was set to gradient in onPause(), restore to black if in all apps.                          
 989          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
 990                                                                                                                    
 991          mPaused = false;                                                                                          
 992          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
 993              setWorkspaceLoading(true);                                                                            
 994              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
 995              mRestoring = false;                                                                                   
 996              mOnResumeNeedsLoad = false;                                                                           
 997          }                                                                                                         
 998          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
 999              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1000              // execute them here                                                                                  
1001              long startTimeCallbacks = 0;                                                                          
1002              if (DEBUG_RESUME_TIME) {                                                                              
1003                  startTimeCallbacks = System.currentTimeMillis();                                                  
1004              }                                                                                                     
1005                                                                                                                    
1006              if (mAppsCustomizeContent != null) {                                                                  
1007                  mAppsCustomizeContent.setBulkBind(true);                                                          
1008              }                                                                                                     
1009              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1010                  mBindOnResumeCallbacks.get(i).run();                                                              
1011              }                                                                                                     
1012              if (mAppsCustomizeContent != null) {                                                                  
1013                  mAppsCustomizeContent.setBulkBind(false);                                                         
1014              }                                                                                                     
1015              mBindOnResumeCallbacks.clear();                                                                       
1016              if (DEBUG_RESUME_TIME) {                                                                              
1017                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1018                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1019              }                                                                                                     
1020          }                                                                                                         
1021          if (mOnResumeCallbacks.size() > 0) {                                                                      
1022              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1023                  mOnResumeCallbacks.get(i).run();                                                                  
1024              }                                                                                                     
1025              mOnResumeCallbacks.clear();                                                                           
1026          }                                                                                                         
1027                                                                                                                    
1028          // Reset the pressed state of icons that were locked in the press state while activities                  
1029          // were launching                                                                                         
1030          if (mWaitingForResume != null) {                                                                          
1031              // Resets the previous workspace icon press state                                                     
1032              mWaitingForResume.setStayPressed(false);                                                              
1033          }                                                                                                         
1034                                                                                                                    
1035          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1036          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1037          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1038          // orientation.                                                                                           
1039          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1040                                                                                                                    
1041          // Process any items that were added while Launcher was away.                                             
1042          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1043                                                                                                                    
1044          // Update the voice search button proxy                                                                   
1045          updateVoiceButtonProxyVisible(false);                                                                     
1046                                                                                                                    
1047          // Again, as with the above scenario, it's possible that one or more of the global icons                  
1048          // were updated in the wrong orientation.                                                                 
1049          updateGlobalIcons();                                                                                      
1050          if (DEBUG_RESUME_TIME) {                                                                                  
1051              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1052          }                                                                                                         
1053                                                                                                                    
1054          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1055              // If we are resuming and the custom content is the current page, we call onShow().                   
1056              // It is also poassible that onShow will instead be called slightly after first layout                
1057              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1058              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1059                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1060              }                                                                                                     
1061          }                                                                                                         
1062          mWorkspace.updateInteractionForState();                                                                   
1063          mWorkspace.onResume();                                                                                    
1064                                                                                                                    
1065          PackageInstallerCompat.getInstance(this).onResume();                                                      
1066      }                                                                                                             
1067                                                                                                                    
1068      @Override                                                                                                     
1069      protected void onPause() {                                                                                    
1070          // Ensure that items added to Launcher are queued until Launcher returns                                  
1071          InstallShortcutReceiver.enableInstallQueue();                                                             
1072          PackageInstallerCompat.getInstance(this).onPause();                                                       
1073                                                                                                                    
1074          super.onPause();                                                                                          
1075          mPaused = true;                                                                                           
1076          mDragController.cancelDrag();                                                                             
1077          mDragController.resetLastGestureUpTime();                                                                 
1078                                                                                                                    
1079          // We call onHide() aggressively. The custom content callbacks should be able to                          
1080          // debounce excess onHide calls.                                                                          
1081          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1082              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1083          }                                                                                                         
1084      }                                                                                                             
1085                                                                                                                    
1086      QSBScroller mQsbScroller = new QSBScroller() {                                                                
1087          int scrollY = 0;                                                                                          
1088                                                                                                                    
1089          @Override                                                                                                 
1090          public void setScrollY(int scroll) {                                                                      
1091              scrollY = scroll;                                                                                     
1092                                                                                                                    
1093              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1094                  mSearchDropTargetBar.setTranslationY(- scrollY);                                                  
1095                  getQsbBar().setTranslationY(-scrollY);                                                            
1096              }                                                                                                     
1097          }                                                                                                         
1098      };                                                                                                            
1099                                                                                                                    
1100      public void resetQSBScroll() {                                                                                
1101          mSearchDropTargetBar.animate().translationY(0).start();                                                   
1102          getQsbBar().animate().translationY(0).start();                                                            
1103      }                                                                                                             
1104                                                                                                                    
1105      public interface CustomContentCallbacks {                                                                     
1106          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1107          // by a onResume or by scrolling otherwise.                                                               
1108          public void onShow(boolean fromResume);                                                                   
1109                                                                                                                    
1110          // Custom content is completely hidden                                                                    
1111          public void onHide();                                                                                     
1112                                                                                                                    
1113          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1114          public void onScrollProgressChanged(float progress);                                                      
1115                                                                                                                    
1116          // Indicates whether the user is allowed to scroll away from the custom content.                          
1117          boolean isScrollingAllowed();                                                                             
1118      }                                                                                                             
1119                                                                                                                    
1120      protected boolean hasSettings() {                                                                             
1121          return false;                                                                                             
1122      }                                                                                                             
1123                                                                                                                    
1124      public interface QSBScroller {                                                                                
1125          public void setScrollY(int scrollY);                                                                      
1126      }                                                                                                             
1127                                                                                                                    
1128      public QSBScroller addToCustomContentPage(View customContent,                                                 
1129              CustomContentCallbacks callbacks, String description) {                                               
1130          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1131          return mQsbScroller;                                                                                      
1132      }                                                                                                             
1133                                                                                                                    
1134      // The custom content needs to offset its content to account for the QSB                                      
1135      public int getTopOffsetForCustomContent() {                                                                   
1136          return mWorkspace.getPaddingTop();                                                                        
1137      }                                                                                                             
1138                                                                                                                    
1139      @Override                                                                                                     
1140      public Object onRetainNonConfigurationInstance() {                                                            
1141          // Flag the loader to stop early before switching                                                         
1142          if (mModel.isCurrentCallbacks(this)) {                                                                    
1143              mModel.stopLoader();                                                                                  
1144          }                                                                                                         
1145          if (mAppsCustomizeContent != null) {                                                                      
1146              mAppsCustomizeContent.surrender();                                                                    
1147          }                                                                                                         
1148          return Boolean.TRUE;                                                                                      
1149      }                                                                                                             
1150                                                                                                                    
1151      // We can't hide the IME if it was forced open.  So don't bother                                              
1152      @Override                                                                                                     
1153      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1154          super.onWindowFocusChanged(hasFocus);                                                                     
1155          mHasFocus = hasFocus;                                                                                     
1156      }                                                                                                             
1157                                                                                                                    
1158      private boolean acceptFilter() {                                                                              
1159          final InputMethodManager inputManager = (InputMethodManager)                                              
1160                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1161          return !inputManager.isFullscreenMode();                                                                  
1162      }                                                                                                             
1163                                                                                                                    
1164      @Override                                                                                                     
1165      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1166          final int uniChar = event.getUnicodeChar();                                                               
1167          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1168          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1169          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1170              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1171                      keyCode, event);                                                                              
1172              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1173                  // something usable has been typed - start a search                                               
1174                  // the typed text will be retrieved and cleared by                                                
1175                  // showSearchDialog()                                                                             
1176                  // If there are multiple keystrokes before the search dialog takes focus,                         
1177                  // onSearchRequested() will be called for every keystroke,                                        
1178                  // but it is idempotent, so it's fine.                                                            
1179                  return onSearchRequested();                                                                       
1180              }                                                                                                     
1181          }                                                                                                         
1182                                                                                                                    
1183          // Eat the long press event so the keyboard doesn't come up.                                              
1184          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1185              return true;                                                                                          
1186          }                                                                                                         
1187                                                                                                                    
1188          return handled;                                                                                           
1189      }                                                                                                             
1190                                                                                                                    
1191      private String getTypedText() {                                                                               
1192          return mDefaultKeySsb.toString();                                                                         
1193      }                                                                                                             
1194                                                                                                                    
1195      private void clearTypedText() {                                                                               
1196          mDefaultKeySsb.clear();                                                                                   
1197          mDefaultKeySsb.clearSpans();                                                                              
1198          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1199      }                                                                                                             
1200                                                                                                                    
1201      /**                                                                                                           
1202       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1203       * State                                                                                                      
1204       */                                                                                                           
1205      private static State intToState(int stateOrdinal) {                                                           
1206          State state = State.WORKSPACE;                                                                            
1207          final State[] stateValues = State.values();                                                               
1208          for (int i = 0; i < stateValues.length; i++) {                                                            
1209              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1210                  state = stateValues[i];                                                                           
1211                  break;                                                                                            
1212              }                                                                                                     
1213          }                                                                                                         
1214          return state;                                                                                             
1215      }                                                                                                             
1216                                                                                                                    
1217      /**                                                                                                           
1218       * Restores the previous state, if it exists.                                                                 
1219       *                                                                                                            
1220       * @param savedState The previous state.                                                                      
1221       */                                                                                                           
1222      @SuppressWarnings("unchecked")                                                                                
1223      private void restoreState(Bundle savedState) {                                                                
1224          if (savedState == null) {                                                                                 
1225              return;                                                                                               
1226          }                                                                                                         
1227                                                                                                                    
1228          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1229          if (state == State.APPS_CUSTOMIZE) {                                                                      
1230              mOnResumeState = State.APPS_CUSTOMIZE;                                                                
1231          }                                                                                                         
1232                                                                                                                    
1233          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1234                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1235          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1236              mWorkspace.setRestorePage(currentScreen);                                                             
1237          }                                                                                                         
1238                                                                                                                    
1239          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1240          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1241                                                                                                                    
1242          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1243              mPendingAddInfo.container = pendingAddContainer;                                                      
1244              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1245              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1246              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1247              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1248              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1249              mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);              
1250              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1251              setWaitingForResult(true);                                                                            
1252              mRestoring = true;                                                                                    
1253          }                                                                                                         
1254                                                                                                                    
1255          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1256          if (renameFolder) {                                                                                       
1257              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1258              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1259              mRestoring = true;                                                                                    
1260          }                                                                                                         
1261                                                                                                                    
1262          // Restore the AppsCustomize tab                                                                          
1263          if (mAppsCustomizeTabHost != null) {                                                                      
1264              String curTab = savedState.getString("apps_customize_currentTab");                                    
1265              if (curTab != null) {                                                                                 
1266                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1267                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1268                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1269                          mAppsCustomizeContent.getCurrentPage());                                                  
1270              }                                                                                                     
1271                                                                                                                    
1272              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1273              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1274          }                                                                                                         
1275          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1276                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1277      }                                                                                                             
1278                                                                                                                    
1279      /**                                                                                                           
1280       * Finds all the views we need and configure them properly.                                                   
1281       */                                                                                                           
1282      private void setupViews() {                                                                                   
1283          final DragController dragController = mDragController;                                                    
1284                                                                                                                    
1285          mLauncherView = findViewById(R.id.launcher);                                                              
1286          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1287          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1288          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1289          mWorkspace.setPageSwitchListener(this);                                                                   
1290          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1291                                                                                                                    
1292          mLauncherView.setSystemUiVisibility(                                                                      
1293                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1294          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1295                                                                                                                    
1296          // Setup the drag layer                                                                                   
1297          mDragLayer.setup(this, dragController);                                                                   
1298                                                                                                                    
1299          // Setup the hotseat                                                                                      
1300          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1301          if (mHotseat != null) {                                                                                   
1302              mHotseat.setup(this);                                                                                 
1303              mHotseat.setOnLongClickListener(this);                                                                
1304          }                                                                                                         
1305                                                                                                                    
1306          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1307          View widgetButton = findViewById(R.id.widget_button);                                                     
1308          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1309              @Override                                                                                             
1310              public void onClick(View arg0) {                                                                      
1311                  if (!mWorkspace.isSwitchingState()) {                                                             
1312                      onClickAddWidgetButton(arg0);                                                                 
1313                  }                                                                                                 
1314              }                                                                                                     
1315          });                                                                                                       
1316          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1317                                                                                                                    
1318          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1319          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1320              @Override                                                                                             
1321              public void onClick(View arg0) {                                                                      
1322                  if (!mWorkspace.isSwitchingState()) {                                                             
1323                      onClickWallpaperPicker(arg0);                                                                 
1324                  }                                                                                                 
1325              }                                                                                                     
1326          });                                                                                                       
1327          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1328                                                                                                                    
1329          View settingsButton = findViewById(R.id.settings_button);                                                 
1330          if (hasSettings()) {                                                                                      
1331              settingsButton.setOnClickListener(new OnClickListener() {                                             
1332                  @Override                                                                                         
1333                  public void onClick(View arg0) {                                                                  
1334                      if (!mWorkspace.isSwitchingState()) {                                                         
1335                          onClickSettingsButton(arg0);                                                              
1336                      }                                                                                             
1337                  }                                                                                                 
1338              });                                                                                                   
1339              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1340          } else {                                                                                                  
1341              settingsButton.setVisibility(View.GONE);                                                              
1342              FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();              
1343              lp.gravity = Gravity.END | Gravity.TOP;                                                               
1344              widgetButton.requestLayout();                                                                         
1345          }                                                                                                         
1346                                                                                                                    
1347          mOverviewPanel.setAlpha(0f);                                                                              
1348                                                                                                                    
1349          // Setup the workspace                                                                                    
1350          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1351          mWorkspace.setOnLongClickListener(this);                                                                  
1352          mWorkspace.setup(dragController);                                                                         
1353          dragController.addDragListener(mWorkspace);                                                               
1354                                                                                                                    
1355          // Get the search/delete bar                                                                              
1356          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1357                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1358                                                                                                                    
1359          // Setup AppsCustomize                                                                                    
1360          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1361          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1362                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1363          mAppsCustomizeContent.setup(this, dragController);                                                        
1364                                                                                                                    
1365          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1366          dragController.setDragScoller(mWorkspace);                                                                
1367          dragController.setScrollView(mDragLayer);                                                                 
1368          dragController.setMoveTarget(mWorkspace);                                                                 
1369          dragController.addDropTarget(mWorkspace);                                                                 
1370          if (mSearchDropTargetBar != null) {                                                                       
1371              mSearchDropTargetBar.setup(this, dragController);                                                     
1372          }                                                                                                         
1373                                                                                                                    
1374          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1375              Log.v(TAG, "adding WeightWatcher");                                                                   
1376              mWeightWatcher = new WeightWatcher(this);                                                             
1377              mWeightWatcher.setAlpha(0.5f);                                                                        
1378              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1379                      new FrameLayout.LayoutParams(                                                                 
1380                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1381                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1382                              Gravity.BOTTOM)                                                                       
1383              );                                                                                                    
1384                                                                                                                    
1385              boolean show = shouldShowWeightWatcher();                                                             
1386              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1387          }                                                                                                         
1388      }                                                                                                             
1389                                                                                                                    
1390      /**                                                                                                           
1391       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1392       */                                                                                                           
1393      public void setAllAppsButton(View allAppsButton) {                                                            
1394          mAllAppsButton = allAppsButton;                                                                           
1395      }                                                                                                             
1396                                                                                                                    
1397      public View getAllAppsButton() {                                                                              
1398          return mAllAppsButton;                                                                                    
1399      }                                                                                                             
1400                                                                                                                    
1401      /**                                                                                                           
1402       * Creates a view representing a shortcut.                                                                    
1403       *                                                                                                            
1404       * @param info The data structure describing the shortcut.                                                    
1405       *                                                                                                            
1406       * @return A View inflated from R.layout.application.                                                         
1407       */                                                                                                           
1408      View createShortcut(ShortcutInfo info) {                                                                      
1409          return createShortcut(R.layout.application,                                                               
1410                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1411      }                                                                                                             
1412                                                                                                                    
1413      /**                                                                                                           
1414       * Creates a view representing a shortcut inflated from the specified resource.                               
1415       *                                                                                                            
1416       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1417       * @param parent The group the shortcut belongs to.                                                           
1418       * @param info The data structure describing the shortcut.                                                    
1419       *                                                                                                            
1420       * @return A View inflated from layoutResId.                                                                  
1421       */                                                                                                           
1422      View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                                   
1423          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1424          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1425          favorite.setOnClickListener(this);                                                                        
1426          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1427          return favorite;                                                                                          
1428      }                                                                                                             
1429                                                                                                                    
1430      /**                                                                                                           
1431       * Add a shortcut to the workspace.                                                                           
1432       *                                                                                                            
1433       * @param data The intent describing the shortcut.                                                            
1434       * @param cellInfo The position on screen where to create the shortcut.                                       
1435       */                                                                                                           
1436      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1437              int cellY) {                                                                                          
1438          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1439          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1440          CellLayout layout = getCellLayout(container, screenId);                                                   
1441                                                                                                                    
1442          boolean foundCellSpan = false;                                                                            
1443                                                                                                                    
1444          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                                      
1445          if (info == null) {                                                                                       
1446              return;                                                                                               
1447          }                                                                                                         
1448          final View view = createShortcut(info);                                                                   
1449                                                                                                                    
1450          // First we check if we already know the exact location where we want to add this item.                   
1451          if (cellX >= 0 && cellY >= 0) {                                                                           
1452              cellXY[0] = cellX;                                                                                    
1453              cellXY[1] = cellY;                                                                                    
1454              foundCellSpan = true;                                                                                 
1455                                                                                                                    
1456              // If appropriate, either create a folder or add to an existing folder                                
1457              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1458                      true, null,null)) {                                                                           
1459                  return;                                                                                           
1460              }                                                                                                     
1461              DragObject dragObject = new DragObject();                                                             
1462              dragObject.dragInfo = info;                                                                           
1463              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1464                      true)) {                                                                                      
1465                  return;                                                                                           
1466              }                                                                                                     
1467          } else if (touchXY != null) {                                                                             
1468              // when dragging and dropping, just find the closest free spot                                        
1469              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1470              foundCellSpan = (result != null);                                                                     
1471          } else {                                                                                                  
1472              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1473          }                                                                                                         
1474                                                                                                                    
1475          if (!foundCellSpan) {                                                                                     
1476              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1477              return;                                                                                               
1478          }                                                                                                         
1479                                                                                                                    
1480          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1481                                                                                                                    
1482          if (!mRestoring) {                                                                                        
1483              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1484                      isWorkspaceLocked());                                                                         
1485          }                                                                                                         
1486      }                                                                                                             
1487                                                                                                                    
1488      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1489              int minHeight) {                                                                                      
1490          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1491          // We want to account for the extra amount of padding that we are adding to the widget                    
1492          // to ensure that it gets the full amount of space that it has requested                                  
1493          int requiredWidth = minWidth + padding.left + padding.right;                                              
1494          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1495          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1496      }                                                                                                             
1497                                                                                                                    
1498      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1499          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1500      }                                                                                                             
1501                                                                                                                    
1502      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1503          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1504      }                                                                                                             
1505                                                                                                                    
1506      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1507          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1508      }                                                                                                             
1509                                                                                                                    
1510      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1511          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1512                  info.minResizeHeight);                                                                            
1513      }                                                                                                             
1514                                                                                                                    
1515      /**                                                                                                           
1516       * Add a widget to the workspace.                                                                             
1517       *                                                                                                            
1518       * @param appWidgetId The app widget id                                                                       
1519       * @param cellInfo The position on screen where to create the widget.                                         
1520       */                                                                                                           
1521      private void completeAddAppWidget(final int appWidgetId, long container, long screenId,                       
1522              AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                                    
1523          if (appWidgetInfo == null) {                                                                              
1524              appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                                      
1525          }                                                                                                         
1526                                                                                                                    
1527          // Calculate the grid spans needed to fit this widget                                                     
1528          CellLayout layout = getCellLayout(container, screenId);                                                   
1529                                                                                                                    
1530          int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                               
1531          int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                                     
1532                                                                                                                    
1533          // Try finding open space on Launcher screen                                                              
1534          // We have saved the position to which the widget was dragged-- this really only matters                  
1535          // if we are placing widgets on a "spring-loaded" screen                                                  
1536          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1537          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1538          int[] finalSpan = new int[2];                                                                             
1539          boolean foundCellSpan = false;                                                                            
1540          if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                           
1541              cellXY[0] = mPendingAddInfo.cellX;                                                                    
1542              cellXY[1] = mPendingAddInfo.cellY;                                                                    
1543              spanXY[0] = mPendingAddInfo.spanX;                                                                    
1544              spanXY[1] = mPendingAddInfo.spanY;                                                                    
1545              foundCellSpan = true;                                                                                 
1546          } else if (touchXY != null) {                                                                             
1547              // when dragging and dropping, just find the closest free spot                                        
1548              int[] result = layout.findNearestVacantArea(                                                          
1549                      touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                                
1550                      spanXY[1], cellXY, finalSpan);                                                                
1551              spanXY[0] = finalSpan[0];                                                                             
1552              spanXY[1] = finalSpan[1];                                                                             
1553              foundCellSpan = (result != null);                                                                     
1554          } else {                                                                                                  
1555              foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                           
1556          }                                                                                                         
1557                                                                                                                    
1558          if (!foundCellSpan) {                                                                                     
1559              if (appWidgetId != -1) {                                                                              
1560                  // Deleting an app widget ID is a void call but writes to disk before returning                   
1561                  // to the caller...                                                                               
1562                  new AsyncTask<Void, Void, Void>() {                                                               
1563                      public Void doInBackground(Void ... args) {                                                   
1564                          mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                            
1565                          return null;                                                                              
1566                      }                                                                                             
1567                  }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                 
1568              }                                                                                                     
1569              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1570              return;                                                                                               
1571          }                                                                                                         
1572                                                                                                                    
1573          // Build Launcher-specific widget info and save to database                                               
1574          LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                               
1575                  appWidgetInfo.provider);                                                                          
1576          launcherInfo.spanX = spanXY[0];                                                                           
1577          launcherInfo.spanY = spanXY[1];                                                                           
1578          launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                         
1579          launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                         
1580          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1581                                                                                                                    
1582          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1583                  container, screenId, cellXY[0], cellXY[1], false);                                                
1584                                                                                                                    
1585          if (!mRestoring) {                                                                                        
1586              if (hostView == null) {                                                                               
1587                  // Perform actual inflation because we're live                                                    
1588                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);              
1589                  launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                                   
1590              } else {                                                                                              
1591                  // The AppWidgetHostView has already been inflated and instantiated                               
1592                  launcherInfo.hostView = hostView;                                                                 
1593              }                                                                                                     
1594                                                                                                                    
1595              launcherInfo.hostView.setTag(launcherInfo);                                                           
1596              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1597              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1598                                                                                                                    
1599              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],              
1600                      launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                                 
1601                                                                                                                    
1602              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1603          }                                                                                                         
1604          resetAddInfo();                                                                                           
1605      }                                                                                                             
1606                                                                                                                    
1607      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1608          @Override                                                                                                 
1609          public void onReceive(Context context, Intent intent) {                                                   
1610              final String action = intent.getAction();                                                             
1611              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1612                  mUserPresent = false;                                                                             
1613                  mDragLayer.clearAllResizeFrames();                                                                
1614                  updateRunning();                                                                                  
1615                                                                                                                    
1616                  // Reset AllApps to its initial state only if we are not in the middle of                         
1617                  // processing a multi-step drop                                                                   
1618                  if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               
1619                      showWorkspace(false);                                                                         
1620                  }                                                                                                 
1621              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1622                  mUserPresent = true;                                                                              
1623                  updateRunning();                                                                                  
1624              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1625                  mModel.resetLoadedState(false, true);                                                             
1626                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1627                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1628              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1629                  mModel.resetLoadedState(false, true);                                                             
1630                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1631                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1632                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1633              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1634                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1635                  getModel().forceReload();                                                                         
1636              }                                                                                                     
1637          }                                                                                                         
1638      };                                                                                                            
1639                                                                                                                    
1640      @Override                                                                                                     
1641      public void onAttachedToWindow() {                                                                            
1642          super.onAttachedToWindow();                                                                               
1643                                                                                                                    
1644          // Listen for broadcasts related to user-presence                                                         
1645          final IntentFilter filter = new IntentFilter();                                                           
1646          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1647          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1648          // For handling managed profiles                                                                          
1649          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1650          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1651          if (ENABLE_DEBUG_INTENTS) {                                                                               
1652              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1653              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1654          }                                                                                                         
1655          registerReceiver(mReceiver, filter);                                                                      
1656          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1657          setupTransparentSystemBarsForLmp();                                                                       
1658          mAttached = true;                                                                                         
1659          mVisible = true;                                                                                          
1660      }                                                                                                             
1661                                                                                                                    
1662      /**                                                                                                           
1663       * Sets up transparent navigation and status bars in LMP.                                                     
1664       * This method is a no-op for other platform versions.                                                        
1665       */                                                                                                           
1666      @TargetApi(19)                                                                                                
1667      private void setupTransparentSystemBarsForLmp() {                                                             
1668          // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1669          // Currently we use reflection to access the flags and the API to set the transparency                    
1670          // on the System bars.                                                                                    
1671          if (Utilities.isLmpOrAbove()) {                                                                           
1672              try {                                                                                                 
1673                  getWindow().getAttributes().systemUiVisibility |=                                                 
1674                          (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1675                                  | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1676                                  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1677                  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1678                          | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1679                  Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1680                          "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1681                  getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1682                                                                                                                    
1683                  Method setStatusBarColorMethod =                                                                  
1684                          Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1685                  Method setNavigationBarColorMethod =                                                              
1686                          Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1687                  setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1688                  setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1689              } catch (NoSuchFieldException e) {                                                                    
1690                  Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1691              } catch (NoSuchMethodException ex) {                                                                  
1692                  Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1693              } catch (IllegalAccessException e) {                                                                  
1694                  Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1695              } catch (IllegalArgumentException e) {                                                                
1696                  Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1697              } catch (InvocationTargetException e) {                                                               
1698                  Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1699              } finally {}                                                                                          
1700          }                                                                                                         
1701      }                                                                                                             
1702                                                                                                                    
1703      @Override                                                                                                     
1704      public void onDetachedFromWindow() {                                                                          
1705          super.onDetachedFromWindow();                                                                             
1706          mVisible = false;                                                                                         
1707                                                                                                                    
1708          if (mAttached) {                                                                                          
1709              unregisterReceiver(mReceiver);                                                                        
1710              mAttached = false;                                                                                    
1711          }                                                                                                         
1712          updateRunning();                                                                                          
1713      }                                                                                                             
1714                                                                                                                    
1715      public void onWindowVisibilityChanged(int visibility) {                                                       
1716          mVisible = visibility == View.VISIBLE;                                                                    
1717          updateRunning();                                                                                          
1718          // The following code used to be in onResume, but it turns out onResume is called when                    
1719          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1720          // is a more appropriate event to handle                                                                  
1721          if (mVisible) {                                                                                           
1722              mAppsCustomizeTabHost.onWindowVisible();                                                              
1723              if (!mWorkspaceLoading) {                                                                             
1724                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1725                  // We want to let Launcher draw itself at least once before we force it to build                  
1726                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1727                  // apps is nice and speedy.                                                                       
1728                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1729                      private boolean mStarted = false;                                                             
1730                      public void onDraw() {                                                                        
1731                          if (mStarted) return;                                                                     
1732                          mStarted = true;                                                                          
1733                          // We delay the layer building a bit in order to give                                     
1734                          // other message processing a time to run.  In particular                                 
1735                          // this avoids a delay in hiding the IME if it was                                        
1736                          // currently shown, because doing that may involve                                        
1737                          // some communication back with the app.                                                  
1738                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1739                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1740                          mWorkspace.post(new Runnable() {                                                          
1741                                  public void run() {                                                               
1742                                      if (mWorkspace != null &&                                                     
1743                                              mWorkspace.getViewTreeObserver() != null) {                           
1744                                          mWorkspace.getViewTreeObserver().                                         
1745                                                  removeOnDrawListener(listener);                                   
1746                                      }                                                                             
1747                                  }                                                                                 
1748                              });                                                                                   
1749                          return;                                                                                   
1750                      }                                                                                             
1751                  });                                                                                               
1752              }                                                                                                     
1753              clearTypedText();                                                                                     
1754          }                                                                                                         
1755      }                                                                                                             
1756                                                                                                                    
1757      private void sendAdvanceMessage(long delay) {                                                                 
1758          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1759          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1760          mHandler.sendMessageDelayed(msg, delay);                                                                  
1761          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1762      }                                                                                                             
1763                                                                                                                    
1764      private void updateRunning() {                                                                                
1765          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1766          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1767              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1768              if (autoAdvanceRunning) {                                                                             
1769                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1770                  sendAdvanceMessage(delay);                                                                        
1771              } else {                                                                                              
1772                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1773                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1774                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1775                  }                                                                                                 
1776                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1777                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1778              }                                                                                                     
1779          }                                                                                                         
1780      }                                                                                                             
1781                                                                                                                    
1782      private final Handler mHandler = new Handler() {                                                              
1783          @Override                                                                                                 
1784          public void handleMessage(Message msg) {                                                                  
1785              if (msg.what == ADVANCE_MSG) {                                                                        
1786                  int i = 0;                                                                                        
1787                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1788                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1789                      final int delay = mAdvanceStagger * i;                                                        
1790                      if (v instanceof Advanceable) {                                                               
1791                         postDelayed(new Runnable() {                                                               
1792                             public void run() {                                                                    
1793                                 ((Advanceable) v).advance();                                                       
1794                             }                                                                                      
1795                         }, delay);                                                                                 
1796                      }                                                                                             
1797                      i++;                                                                                          
1798                  }                                                                                                 
1799                  sendAdvanceMessage(mAdvanceInterval);                                                             
1800              }                                                                                                     
1801          }                                                                                                         
1802      };                                                                                                            
1803                                                                                                                    
1804      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1805          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1806          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1807          if (v instanceof Advanceable) {                                                                           
1808              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1809              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1810              updateRunning();                                                                                      
1811          }                                                                                                         
1812      }                                                                                                             
1813                                                                                                                    
1814      void removeWidgetToAutoAdvance(View hostView) {                                                               
1815          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1816              mWidgetsToAdvance.remove(hostView);                                                                   
1817              updateRunning();                                                                                      
1818          }                                                                                                         
1819      }                                                                                                             
1820                                                                                                                    
1821      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1822          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1823          launcherInfo.hostView = null;                                                                             
1824      }                                                                                                             
1825                                                                                                                    
1826      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
1827          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1828          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1829      }                                                                                                             
1830                                                                                                                    
1831      public DragLayer getDragLayer() {                                                                             
1832          return mDragLayer;                                                                                        
1833      }                                                                                                             
1834                                                                                                                    
1835      public Workspace getWorkspace() {                                                                             
1836          return mWorkspace;                                                                                        
1837      }                                                                                                             
1838                                                                                                                    
1839      public Hotseat getHotseat() {                                                                                 
1840          return mHotseat;                                                                                          
1841      }                                                                                                             
1842                                                                                                                    
1843      public ViewGroup getOverviewPanel() {                                                                         
1844          return mOverviewPanel;                                                                                    
1845      }                                                                                                             
1846                                                                                                                    
1847      public SearchDropTargetBar getSearchBar() {                                                                   
1848          return mSearchDropTargetBar;                                                                              
1849      }                                                                                                             
1850                                                                                                                    
1851      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
1852          return mAppWidgetHost;                                                                                    
1853      }                                                                                                             
1854                                                                                                                    
1855      public LauncherModel getModel() {                                                                             
1856          return mModel;                                                                                            
1857      }                                                                                                             
1858                                                                                                                    
1859      protected SharedPreferences getSharedPrefs() {                                                                
1860          return mSharedPrefs;                                                                                      
1861      }                                                                                                             
1862                                                                                                                    
1863      public void closeSystemDialogs() {                                                                            
1864          getWindow().closeAllPanels();                                                                             
1865                                                                                                                    
1866          // Whatever we were doing is hereby canceled.                                                             
1867          setWaitingForResult(false);                                                                               
1868      }                                                                                                             
1869                                                                                                                    
1870      @Override                                                                                                     
1871      protected void onNewIntent(Intent intent) {                                                                   
1872          long startTime = 0;                                                                                       
1873          if (DEBUG_RESUME_TIME) {                                                                                  
1874              startTime = System.currentTimeMillis();                                                               
1875          }                                                                                                         
1876          super.onNewIntent(intent);                                                                                
1877                                                                                                                    
1878          // Close the menu                                                                                         
1879          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
1880              // also will cancel mWaitingForResult.                                                                
1881              closeSystemDialogs();                                                                                 
1882                                                                                                                    
1883              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
1884                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
1885                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
1886                                                                                                                    
1887              if (mWorkspace == null) {                                                                             
1888                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
1889                  return;                                                                                           
1890              }                                                                                                     
1891              Folder openFolder = mWorkspace.getOpenFolder();                                                       
1892              // In all these cases, only animate if we're already on home                                          
1893              mWorkspace.exitWidgetResizeMode();                                                                    
1894              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
1895                      openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                              
1896                  mWorkspace.moveToDefaultScreen(true);                                                             
1897              }                                                                                                     
1898                                                                                                                    
1899              closeFolder();                                                                                        
1900              exitSpringLoadedDragMode();                                                                           
1901                                                                                                                    
1902              // If we are already on home, then just animate back to the workspace,                                
1903              // otherwise, just wait until onResume to set the state back to Workspace                             
1904              if (alreadyOnHome) {                                                                                  
1905                  showWorkspace(true);                                                                              
1906              } else {                                                                                              
1907                  mOnResumeState = State.WORKSPACE;                                                                 
1908              }                                                                                                     
1909                                                                                                                    
1910              final View v = getWindow().peekDecorView();                                                           
1911              if (v != null && v.getWindowToken() != null) {                                                        
1912                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
1913                          INPUT_METHOD_SERVICE);                                                                    
1914                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
1915              }                                                                                                     
1916                                                                                                                    
1917              // Reset the apps customize page                                                                      
1918              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
1919                  mAppsCustomizeTabHost.reset();                                                                    
1920              }                                                                                                     
1921                                                                                                                    
1922              onHomeIntent();                                                                                       
1923          }                                                                                                         
1924                                                                                                                    
1925          if (DEBUG_RESUME_TIME) {                                                                                  
1926              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
1927          }                                                                                                         
1928      }                                                                                                             
1929                                                                                                                    
1930      /**                                                                                                           
1931       * Override point for subclasses to prevent movement to the default screen when the home                      
1932       * button is pressed. Used (for example) in GEL, to prevent movement during a search.                         
1933       */                                                                                                           
1934      protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                                   
1935          return true;                                                                                              
1936      }                                                                                                             
1937                                                                                                                    
1938      /**                                                                                                           
1939       * Override point for subclasses to provide custom behaviour for when a home intent is fired.                 
1940       */                                                                                                           
1941      protected void onHomeIntent() {                                                                               
1942          // Do nothing                                                                                             
1943      }                                                                                                             
1944                                                                                                                    
1945      @Override                                                                                                     
1946      public void onRestoreInstanceState(Bundle state) {                                                            
1947          super.onRestoreInstanceState(state);                                                                      
1948          for (int page: mSynchronouslyBoundPages) {                                                                
1949              mWorkspace.restoreInstanceStateForChild(page);                                                        
1950          }                                                                                                         
1951      }                                                                                                             
1952                                                                                                                    
1953      @Override                                                                                                     
1954      protected void onSaveInstanceState(Bundle outState) {                                                         
1955          if (mWorkspace.getChildCount() > 0) {                                                                     
1956              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
1957                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
1958          }                                                                                                         
1959          super.onSaveInstanceState(outState);                                                                      
1960                                                                                                                    
1961          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
1962          // We close any open folder since it will not be re-opened, and we need to make sure                      
1963          // this state is reflected.                                                                               
1964          closeFolder();                                                                                            
1965                                                                                                                    
1966          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
1967                  mWaitingForResult) {                                                                              
1968              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
1969              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
1970              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
1971              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
1972              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
1973              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
1974              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
1975              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
1976          }                                                                                                         
1977                                                                                                                    
1978          if (mFolderInfo != null && mWaitingForResult) {                                                           
1979              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
1980              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
1981          }                                                                                                         
1982                                                                                                                    
1983          // Save the current AppsCustomize tab                                                                     
1984          if (mAppsCustomizeTabHost != null) {                                                                      
1985              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
1986              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
1987              if (currentTabTag != null) {                                                                          
1988                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
1989              }                                                                                                     
1990              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
1991              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
1992          }                                                                                                         
1993          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
1994      }                                                                                                             
1995                                                                                                                    
1996      @Override                                                                                                     
1997      public void onDestroy() {                                                                                     
1998          super.onDestroy();                                                                                        
1999                                                                                                                    
2000          // Remove all pending runnables                                                                           
2001          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2002          mHandler.removeMessages(0);                                                                               
2003          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2004                                                                                                                    
2005          // Stop callbacks from LauncherModel                                                                      
2006          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2007                                                                                                                    
2008          // It's possible to receive onDestroy after a new Launcher activity has                                   
2009          // been created. In this case, don't interfere with the new Launcher.                                     
2010          if (mModel.isCurrentCallbacks(this)) {                                                                    
2011              mModel.stopLoader();                                                                                  
2012              app.setLauncher(null);                                                                                
2013          }                                                                                                         
2014                                                                                                                    
2015          try {                                                                                                     
2016              mAppWidgetHost.stopListening();                                                                       
2017          } catch (NullPointerException ex) {                                                                       
2018              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2019          }                                                                                                         
2020          mAppWidgetHost = null;                                                                                    
2021                                                                                                                    
2022          mWidgetsToAdvance.clear();                                                                                
2023                                                                                                                    
2024          TextKeyListener.getInstance().release();                                                                  
2025                                                                                                                    
2026          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2027          // to prevent leaking Launcher activities on orientation change.                                          
2028          if (mModel != null) {                                                                                     
2029              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2030          }                                                                                                         
2031                                                                                                                    
2032          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2033          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2034                                                                                                                    
2035          mDragLayer.clearAllResizeFrames();                                                                        
2036          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2037          mWorkspace.removeAllWorkspaceScreens();                                                                   
2038          mWorkspace = null;                                                                                        
2039          mDragController = null;                                                                                   
2040                                                                                                                    
2041          PackageInstallerCompat.getInstance(this).onStop();                                                        
2042          LauncherAnimUtils.onDestroyActivity();                                                                    
2043      }                                                                                                             
2044                                                                                                                    
2045      public DragController getDragController() {                                                                   
2046          return mDragController;                                                                                   
2047      }                                                                                                             
2048                                                                                                                    
2049      @Override                                                                                                     
2050      public void startActivityForResult(Intent intent, int requestCode) {                                          
2051          if (requestCode >= 0) {                                                                                   
2052              setWaitingForResult(true);                                                                            
2053          }                                                                                                         
2054          super.startActivityForResult(intent, requestCode);                                                        
2055      }                                                                                                             
2056                                                                                                                    
2057      /**                                                                                                           
2058       * Indicates that we want global search for this activity by setting the globalSearch                         
2059       * argument for {@link #startSearch} to true.                                                                 
2060       */                                                                                                           
2061      @Override                                                                                                     
2062      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2063              Bundle appSearchData, boolean globalSearch) {                                                         
2064                                                                                                                    
2065          showWorkspace(true);                                                                                      
2066                                                                                                                    
2067          if (initialQuery == null) {                                                                               
2068              // Use any text typed in the launcher as the initial query                                            
2069              initialQuery = getTypedText();                                                                        
2070          }                                                                                                         
2071          if (appSearchData == null) {                                                                              
2072              appSearchData = new Bundle();                                                                         
2073              appSearchData.putString("source", "launcher-search");                                                 
2074          }                                                                                                         
2075          Rect sourceBounds = new Rect();                                                                           
2076          if (mSearchDropTargetBar != null) {                                                                       
2077              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2078          }                                                                                                         
2079                                                                                                                    
2080          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2081                  appSearchData, sourceBounds);                                                                     
2082          if (clearTextImmediately) {                                                                               
2083              clearTypedText();                                                                                     
2084          }                                                                                                         
2085      }                                                                                                             
2086                                                                                                                    
2087      /**                                                                                                           
2088       * Start a text search.                                                                                       
2089       *                                                                                                            
2090       * @return {@code true} if the search will start immediately, so any further keypresses                       
2091       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2092       * to buffer keypresses.                                                                                      
2093       */                                                                                                           
2094      public boolean startSearch(String initialQuery,                                                               
2095              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2096          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2097                  appSearchData, sourceBounds);                                                                     
2098          return false;                                                                                             
2099      }                                                                                                             
2100                                                                                                                    
2101      /**                                                                                                           
2102       * Starts the global search activity. This code is a copied from SearchManager                                
2103       */                                                                                                           
2104      private void startGlobalSearch(String initialQuery,                                                           
2105              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2106          final SearchManager searchManager =                                                                       
2107              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2108          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2109          if (globalSearchActivity == null) {                                                                       
2110              Log.w(TAG, "No global search activity found.");                                                       
2111              return;                                                                                               
2112          }                                                                                                         
2113          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2114          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2115          intent.setComponent(globalSearchActivity);                                                                
2116          // Make sure that we have a Bundle to put source in                                                       
2117          if (appSearchData == null) {                                                                              
2118              appSearchData = new Bundle();                                                                         
2119          } else {                                                                                                  
2120              appSearchData = new Bundle(appSearchData);                                                            
2121          }                                                                                                         
2122          // Set source to package name of app that starts global search, if not set already.                       
2123          if (!appSearchData.containsKey("source")) {                                                               
2124              appSearchData.putString("source", getPackageName());                                                  
2125          }                                                                                                         
2126          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2127          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2128              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2129          }                                                                                                         
2130          if (selectInitialQuery) {                                                                                 
2131              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2132          }                                                                                                         
2133          intent.setSourceBounds(sourceBounds);                                                                     
2134          try {                                                                                                     
2135              startActivity(intent);                                                                                
2136          } catch (ActivityNotFoundException ex) {                                                                  
2137              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2138          }                                                                                                         
2139      }                                                                                                             
2140                                                                                                                    
2141      public boolean isOnCustomContent() {                                                                          
2142          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2143      }                                                                                                             
2144                                                                                                                    
2145      @Override                                                                                                     
2146      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2147          super.onPrepareOptionsMenu(menu);                                                                         
2148          if (!isOnCustomContent()) {                                                                               
2149              // Close any open folders                                                                             
2150              closeFolder();                                                                                        
2151              // Stop resizing any widgets                                                                          
2152              mWorkspace.exitWidgetResizeMode();                                                                    
2153              if (!mWorkspace.isInOverviewMode()) {                                                                 
2154                  // Show the overview mode                                                                         
2155                  showOverviewMode(true);                                                                           
2156              } else {                                                                                              
2157                  showWorkspace(true);                                                                              
2158              }                                                                                                     
2159          }                                                                                                         
2160          return false;                                                                                             
2161      }                                                                                                             
2162                                                                                                                    
2163      @Override                                                                                                     
2164      public boolean onSearchRequested() {                                                                          
2165          startSearch(null, false, null, true);                                                                     
2166          // Use a custom animation for launching search                                                            
2167          return true;                                                                                              
2168      }                                                                                                             
2169                                                                                                                    
2170      public boolean isWorkspaceLocked() {                                                                          
2171          return mWorkspaceLoading || mWaitingForResult;                                                            
2172      }                                                                                                             
2173                                                                                                                    
2174      public boolean isWorkspaceLoading() {                                                                         
2175          return mWorkspaceLoading;                                                                                 
2176      }                                                                                                             
2177                                                                                                                    
2178      private void setWorkspaceLoading(boolean value) {                                                             
2179          boolean isLocked = isWorkspaceLocked();                                                                   
2180          mWorkspaceLoading = value;                                                                                
2181          if (isLocked != isWorkspaceLocked()) {                                                                    
2182              onWorkspaceLockedChanged();                                                                           
2183          }                                                                                                         
2184      }                                                                                                             
2185                                                                                                                    
2186      private void setWaitingForResult(boolean value) {                                                             
2187          boolean isLocked = isWorkspaceLocked();                                                                   
2188          mWaitingForResult = value;                                                                                
2189          if (isLocked != isWorkspaceLocked()) {                                                                    
2190              onWorkspaceLockedChanged();                                                                           
2191          }                                                                                                         
2192      }                                                                                                             
2193                                                                                                                    
2194      protected void onWorkspaceLockedChanged() { }                                                                 
2195                                                                                                                    
2196      private void resetAddInfo() {                                                                                 
2197          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2198          mPendingAddInfo.screenId = -1;                                                                            
2199          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2200          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2201          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2202          mPendingAddInfo.dropPos = null;                                                                           
2203      }                                                                                                             
2204                                                                                                                    
2205      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2206              final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {                     
2207          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2208      }                                                                                                             
2209                                                                                                                    
2210      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2211              final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int                   
2212              delay) {                                                                                              
2213          if (appWidgetInfo.configure != null) {                                                                    
2214              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2215              mPendingAddWidgetId = appWidgetId;                                                                    
2216                                                                                                                    
2217              // Launch over to configure widget, if needed                                                         
2218              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2219                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2220                                                                                                                    
2221          } else {                                                                                                  
2222              // Otherwise just add it                                                                              
2223              Runnable onComplete = new Runnable() {                                                                
2224                  @Override                                                                                         
2225                  public void run() {                                                                               
2226                      // Exit spring loaded mode if necessary after adding the widget                               
2227                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2228                              null);                                                                                
2229                  }                                                                                                 
2230              };                                                                                                    
2231              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2232                      appWidgetInfo);                                                                               
2233              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2234          }                                                                                                         
2235      }                                                                                                             
2236                                                                                                                    
2237      protected void moveToCustomContentScreen(boolean animate) {                                                   
2238          // Close any folders that may be open.                                                                    
2239          closeFolder();                                                                                            
2240          mWorkspace.moveToCustomContentScreen(animate);                                                            
2241      }                                                                                                             
2242      /**                                                                                                           
2243       * Process a shortcut drop.                                                                                   
2244       *                                                                                                            
2245       * @param componentName The name of the component                                                             
2246       * @param screenId The ID of the screen where it should be added                                              
2247       * @param cell The cell it should be added to, optional                                                       
2248       * @param position The location on the screen where it was dropped, optional                                  
2249       */                                                                                                           
2250      void processShortcutFromDrop(ComponentName componentName, long container, long screenId,                      
2251              int[] cell, int[] loc) {                                                                              
2252          resetAddInfo();                                                                                           
2253          mPendingAddInfo.container = container;                                                                    
2254          mPendingAddInfo.screenId = screenId;                                                                      
2255          mPendingAddInfo.dropPos = loc;                                                                            
2256                                                                                                                    
2257          if (cell != null) {                                                                                       
2258              mPendingAddInfo.cellX = cell[0];                                                                      
2259              mPendingAddInfo.cellY = cell[1];                                                                      
2260          }                                                                                                         
2261                                                                                                                    
2262          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2263          createShortcutIntent.setComponent(componentName);                                                         
2264          processShortcut(createShortcutIntent);                                                                    
2265      }                                                                                                             
2266                                                                                                                    
2267      /**                                                                                                           
2268       * Process a widget drop.                                                                                     
2269       *                                                                                                            
2270       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2271       * @param screenId The ID of the screen where it should be added                                              
2272       * @param cell The cell it should be added to, optional                                                       
2273       * @param position The location on the screen where it was dropped, optional                                  
2274       */                                                                                                           
2275      void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                           
2276              int[] cell, int[] span, int[] loc) {                                                                  
2277          resetAddInfo();                                                                                           
2278          mPendingAddInfo.container = info.container = container;                                                   
2279          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2280          mPendingAddInfo.dropPos = loc;                                                                            
2281          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2282          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2283                                                                                                                    
2284          if (cell != null) {                                                                                       
2285              mPendingAddInfo.cellX = cell[0];                                                                      
2286              mPendingAddInfo.cellY = cell[1];                                                                      
2287          }                                                                                                         
2288          if (span != null) {                                                                                       
2289              mPendingAddInfo.spanX = span[0];                                                                      
2290              mPendingAddInfo.spanY = span[1];                                                                      
2291          }                                                                                                         
2292                                                                                                                    
2293          AppWidgetHostView hostView = info.boundWidget;                                                            
2294          int appWidgetId;                                                                                          
2295          if (hostView != null) {                                                                                   
2296              appWidgetId = hostView.getAppWidgetId();                                                              
2297              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2298          } else {                                                                                                  
2299              // In this case, we either need to start an activity to get permission to bind                        
2300              // the widget, or we need to start an activity to configure the widget, or both.                      
2301              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2302              Bundle options = info.bindOptions;                                                                    
2303                                                                                                                    
2304              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2305                      appWidgetId, info.info, options);                                                             
2306              if (success) {                                                                                        
2307                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2308              } else {                                                                                              
2309                  mPendingAddWidgetInfo = info.info;                                                                
2310                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2311                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2312                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2313                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2314                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2315                  // TODO: we need to make sure that this accounts for the options bundle.                          
2316                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2317                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2318              }                                                                                                     
2319          }                                                                                                         
2320      }                                                                                                             
2321                                                                                                                    
2322      void processShortcut(Intent intent) {                                                                         
2323          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2324      }                                                                                                             
2325                                                                                                                    
2326      void processWallpaper(Intent intent) {                                                                        
2327          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2328      }                                                                                                             
2329                                                                                                                    
2330      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2331              int cellY) {                                                                                          
2332          final FolderInfo folderInfo = new FolderInfo();                                                           
2333          folderInfo.title = getText(R.string.folder_name);                                                         
2334                                                                                                                    
2335          // Update the model                                                                                       
2336          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2337                  false);                                                                                           
2338          sFolders.put(folderInfo.id, folderInfo);                                                                  
2339                                                                                                                    
2340          // Create the view                                                                                        
2341          FolderIcon newFolder =                                                                                    
2342              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2343          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2344                  isWorkspaceLocked());                                                                             
2345          // Force measure the new folder icon                                                                      
2346          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2347          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2348          return newFolder;                                                                                         
2349      }                                                                                                             
2350                                                                                                                    
2351      void removeFolder(FolderInfo folder) {                                                                        
2352          sFolders.remove(folder.id);                                                                               
2353      }                                                                                                             
2354                                                                                                                    
2355      protected ComponentName getWallpaperPickerComponent() {                                                       
2356          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2357      }                                                                                                             
2358                                                                                                                    
2359      /**                                                                                                           
2360       * Registers various content observers. The current implementation registers                                  
2361       * only a favorites observer to keep track of the favorites applications.                                     
2362       */                                                                                                           
2363      private void registerContentObservers() {                                                                     
2364          ContentResolver resolver = getContentResolver();                                                          
2365          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2366                  true, mWidgetObserver);                                                                           
2367      }                                                                                                             
2368                                                                                                                    
2369      @Override                                                                                                     
2370      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2371          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2372              switch (event.getKeyCode()) {                                                                         
2373                  case KeyEvent.KEYCODE_HOME:                                                                       
2374                      return true;                                                                                  
2375                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2376                      if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                                 
2377                          dumpState();                                                                              
2378                          return true;                                                                              
2379                      }                                                                                             
2380                      break;                                                                                        
2381              }                                                                                                     
2382          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2383              switch (event.getKeyCode()) {                                                                         
2384                  case KeyEvent.KEYCODE_HOME:                                                                       
2385                      return true;                                                                                  
2386              }                                                                                                     
2387          }                                                                                                         
2388                                                                                                                    
2389          return super.dispatchKeyEvent(event);                                                                     
2390      }                                                                                                             
2391                                                                                                                    
2392      @Override                                                                                                     
2393      public void onBackPressed() {                                                                                 
2394          if (isAllAppsVisible()) {                                                                                 
2395              if (mAppsCustomizeContent.getContentType() ==                                                         
2396                      AppsCustomizePagedView.ContentType.Applications) {                                            
2397                  showWorkspace(true);                                                                              
2398              } else {                                                                                              
2399                  showOverviewMode(true);                                                                           
2400              }                                                                                                     
2401          } else if (mWorkspace.isInOverviewMode()) {                                                               
2402              mWorkspace.exitOverviewMode(true);                                                                    
2403          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2404              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2405              if (openFolder.isEditingName()) {                                                                     
2406                  openFolder.dismissEditingName();                                                                  
2407              } else {                                                                                              
2408                  closeFolder();                                                                                    
2409              }                                                                                                     
2410          } else {                                                                                                  
2411              mWorkspace.exitWidgetResizeMode();                                                                    
2412                                                                                                                    
2413              // Back button is a no-op here, but give at least some feedback for the button press                  
2414              mWorkspace.showOutlinesTemporarily();                                                                 
2415          }                                                                                                         
2416      }                                                                                                             
2417                                                                                                                    
2418      /**                                                                                                           
2419       * Re-listen when widgets are reset.                                                                          
2420       */                                                                                                           
2421      private void onAppWidgetReset() {                                                                             
2422          if (mAppWidgetHost != null) {                                                                             
2423              mAppWidgetHost.startListening();                                                                      
2424          }                                                                                                         
2425      }                                                                                                             
2426                                                                                                                    
2427      /**                                                                                                           
2428       * Launches the intent referred by the clicked shortcut.                                                      
2429       *                                                                                                            
2430       * @param v The view representing the clicked shortcut.                                                       
2431       */                                                                                                           
2432      public void onClick(View v) {                                                                                 
2433          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2434          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2435          if (v.getWindowToken() == null) {                                                                         
2436              return;                                                                                               
2437          }                                                                                                         
2438                                                                                                                    
2439          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2440              return;                                                                                               
2441          }                                                                                                         
2442                                                                                                                    
2443          if (v instanceof Workspace) {                                                                             
2444              if (mWorkspace.isInOverviewMode()) {                                                                  
2445                  mWorkspace.exitOverviewMode(true);                                                                
2446              }                                                                                                     
2447              return;                                                                                               
2448          }                                                                                                         
2449                                                                                                                    
2450          if (v instanceof CellLayout) {                                                                            
2451              if (mWorkspace.isInOverviewMode()) {                                                                  
2452                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2453              }                                                                                                     
2454          }                                                                                                         
2455                                                                                                                    
2456          Object tag = v.getTag();                                                                                  
2457          if (tag instanceof ShortcutInfo) {                                                                        
2458              onClickAppShortcut(v);                                                                                
2459          } else if (tag instanceof FolderInfo) {                                                                   
2460              if (v instanceof FolderIcon) {                                                                        
2461                  onClickFolderIcon(v);                                                                             
2462              }                                                                                                     
2463          } else if (v == mAllAppsButton) {                                                                         
2464              onClickAllAppsButton(v);                                                                              
2465          } else if (tag instanceof AppInfo) {                                                                      
2466              startAppShortcutOrInfoActivity(v);                                                                    
2467          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2468              if (v instanceof PendingAppWidgetHostView) {                                                          
2469                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2470              }                                                                                                     
2471          }                                                                                                         
2472      }                                                                                                             
2473                                                                                                                    
2474      public void onClickPagedViewIcon(View v) {                                                                    
2475          startAppShortcutOrInfoActivity(v);                                                                        
2476      }                                                                                                             
2477                                                                                                                    
2478      public boolean onTouch(View v, MotionEvent event) {                                                           
2479          return false;                                                                                             
2480      }                                                                                                             
2481                                                                                                                    
2482      /**                                                                                                           
2483       * Event handler for the app widget view which has not fully restored.                                        
2484       */                                                                                                           
2485      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2486          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2487          if (v.isReadyForClickSetup()) {                                                                           
2488              int widgetId = info.appWidgetId;                                                                      
2489              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2490              if (appWidgetInfo != null) {                                                                          
2491                  mPendingAddWidgetInfo = appWidgetInfo;                                                            
2492                  mPendingAddInfo.copyFrom(info);                                                                   
2493                  mPendingAddWidgetId = widgetId;                                                                   
2494                                                                                                                    
2495                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2496                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2497              }                                                                                                     
2498          } else if (info.installProgress < 0) {                                                                    
2499              // The install has not been queued                                                                    
2500              final String packageName = info.providerName.getPackageName();                                        
2501              showBrokenAppInstallDialog(packageName,                                                               
2502                  new DialogInterface.OnClickListener() {                                                           
2503                      public void onClick(DialogInterface dialog, int id) {                                         
2504                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2505                      }                                                                                             
2506                  });                                                                                               
2507          } else {                                                                                                  
2508              // Download has started.                                                                              
2509              final String packageName = info.providerName.getPackageName();                                        
2510              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2511          }                                                                                                         
2512      }                                                                                                             
2513                                                                                                                    
2514      /**                                                                                                           
2515       * Event handler for the search button                                                                        
2516       *                                                                                                            
2517       * @param v The view that was clicked.                                                                        
2518       */                                                                                                           
2519      public void onClickSearchButton(View v) {                                                                     
2520          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2521                                                                                                                    
2522          onSearchRequested();                                                                                      
2523      }                                                                                                             
2524                                                                                                                    
2525      /**                                                                                                           
2526       * Event handler for the voice button                                                                         
2527       *                                                                                                            
2528       * @param v The view that was clicked.                                                                        
2529       */                                                                                                           
2530      public void onClickVoiceButton(View v) {                                                                      
2531          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2532                                                                                                                    
2533          startVoice();                                                                                             
2534      }                                                                                                             
2535                                                                                                                    
2536      public void startVoice() {                                                                                    
2537          try {                                                                                                     
2538              final SearchManager searchManager =                                                                   
2539                      (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                     
2540              ComponentName activityName = searchManager.getGlobalSearchActivity();                                 
2541              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
2542              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                       
2543              if (activityName != null) {                                                                           
2544                  intent.setPackage(activityName.getPackageName());                                                 
2545              }                                                                                                     
2546              startActivity(null, intent, "onClickVoiceButton");                                                    
2547          } catch (ActivityNotFoundException e) {                                                                   
2548              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
2549              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                       
2550              startActivitySafely(null, intent, "onClickVoiceButton");                                              
2551          }                                                                                                         
2552      }                                                                                                             
2553                                                                                                                    
2554      /**                                                                                                           
2555       * Event handler for the "grid" button that appears on the home screen, which                                 
2556       * enters all apps mode.                                                                                      
2557       *                                                                                                            
2558       * @param v The view that was clicked.                                                                        
2559       */                                                                                                           
2560      protected void onClickAllAppsButton(View v) {                                                                 
2561          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2562          if (isAllAppsVisible()) {                                                                                 
2563              showWorkspace(true);                                                                                  
2564          } else {                                                                                                  
2565              showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2566          }                                                                                                         
2567      }                                                                                                             
2568                                                                                                                    
2569      private void showBrokenAppInstallDialog(final String packageName,                                             
2570              DialogInterface.OnClickListener onSearchClickListener) {                                              
2571 -        new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))               
2572 +        new AlertDialog.Builder(this)                                                                             
2573              .setTitle(R.string.abandoned_promises_title)                                                          
2574              .setMessage(R.string.abandoned_promise_explanation)                                                   
2575              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2576              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2577                  new DialogInterface.OnClickListener() {                                                           
2578                      public void onClick(DialogInterface dialog, int id) {                                         
2579                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2580                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2581                      }                                                                                             
2582                  })                                                                                                
2583              .create().show();                                                                                     
2584          return;                                                                                                   
2585      }                                                                                                             
2586                                                                                                                    
2587      /**                                                                                                           
2588       * Event handler for an app shortcut click.                                                                   
2589       *                                                                                                            
2590       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2591       */                                                                                                           
2592      protected void onClickAppShortcut(final View v) {                                                             
2593          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2594          Object tag = v.getTag();                                                                                  
2595          if (!(tag instanceof ShortcutInfo)) {                                                                     
2596              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2597          }                                                                                                         
2598                                                                                                                    
2599          // Open shortcut                                                                                          
2600          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2601 +                                                                                                                  
2602 +        if (shortcut.isDisabled != 0) {                                                                           
2603 +            int error = R.string.activity_not_available;                                                          
2604 +            if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2605 +                error = R.string.safemode_shortcut_error;                                                         
2606 +            }                                                                                                     
2607 +            Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2608 +            return;                                                                                               
2609 +        }                                                                                                         
2610 +                                                                                                                  
2611          final Intent intent = shortcut.intent;                                                                    
2612                                                                                                                    
2613          // Check for special shortcuts                                                                            
2614          if (intent.getComponent() != null) {                                                                      
2615              final String shortcutClass = intent.getComponent().getClassName();                                    
2616                                                                                                                    
2617              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2618                  MemoryDumpActivity.startDump(this);                                                               
2619                  return;                                                                                           
2620              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2621                  toggleShowWeightWatcher();                                                                        
2622                  return;                                                                                           
2623              }                                                                                                     
2624          }                                                                                                         
2625                                                                                                                    
2626          // Check for abandoned promise                                                                            
2627          if ((v instanceof BubbleTextView)                                                                         
2628                  && shortcut.isPromise()                                                                           
2629                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2630              showBrokenAppInstallDialog(                                                                           
2631                      shortcut.getTargetComponent().getPackageName(),                                               
2632                      new DialogInterface.OnClickListener() {                                                       
2633                          public void onClick(DialogInterface dialog, int id) {                                     
2634                              startAppShortcutOrInfoActivity(v);                                                    
2635                          }                                                                                         
2636                      });                                                                                           
2637              return;                                                                                               
2638          }                                                                                                         
2639                                                                                                                    
2640          // Start activities                                                                                       
2641          startAppShortcutOrInfoActivity(v);                                                                        
2642      }                                                                                                             
2643                                                                                                                    
2644      private void startAppShortcutOrInfoActivity(View v) {                                                         
2645          Object tag = v.getTag();                                                                                  
2646          final ShortcutInfo shortcut;                                                                              
2647          final Intent intent;                                                                                      
2648          if (tag instanceof ShortcutInfo) {                                                                        
2649              shortcut = (ShortcutInfo) tag;                                                                        
2650              intent = shortcut.intent;                                                                             
2651              int[] pos = new int[2];                                                                               
2652              v.getLocationOnScreen(pos);                                                                           
2653              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2654                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2655                                                                                                                    
2656          } else if (tag instanceof AppInfo) {                                                                      
2657              shortcut = null;                                                                                      
2658              intent = ((AppInfo) tag).intent;                                                                      
2659          } else {                                                                                                  
2660              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2661          }                                                                                                         
2662                                                                                                                    
2663          boolean success = startActivitySafely(v, intent, tag);                                                    
2664          mStats.recordLaunch(intent, shortcut);                                                                    
2665                                                                                                                    
2666          if (success && v instanceof BubbleTextView) {                                                             
2667              mWaitingForResume = (BubbleTextView) v;                                                               
2668              mWaitingForResume.setStayPressed(true);                                                               
2669          }                                                                                                         
2670      }                                                                                                             
2671                                                                                                                    
2672      /**                                                                                                           
2673       * Event handler for a folder icon click.                                                                     
2674       *                                                                                                            
2675       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2676       */                                                                                                           
2677      protected void onClickFolderIcon(View v) {                                                                    
2678          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2679          if (!(v instanceof FolderIcon)){                                                                          
2680              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2681          }                                                                                                         
2682                                                                                                                    
2683          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2684          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2685          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2686                                                                                                                    
2687          // If the folder info reports that the associated folder is open, then verify that                        
2688          // it is actually opened. There have been a few instances where this gets out of sync.                    
2689          if (info.opened && openFolder == null) {                                                                  
2690              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2691                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2692              info.opened = false;                                                                                  
2693          }                                                                                                         
2694                                                                                                                    
2695          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2696              // Close any open folder                                                                              
2697              closeFolder();                                                                                        
2698              // Open the requested folder                                                                          
2699              openFolder(folderIcon);                                                                               
2700          } else {                                                                                                  
2701              // Find the open folder...                                                                            
2702              int folderScreen;                                                                                     
2703              if (openFolder != null) {                                                                             
2704                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2705                  // .. and close it                                                                                
2706                  closeFolder(openFolder);                                                                          
2707                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2708                      // Close any folder open on the current screen                                                
2709                      closeFolder();                                                                                
2710                      // Pull the folder onto this screen                                                           
2711                      openFolder(folderIcon);                                                                       
2712                  }                                                                                                 
2713              }                                                                                                     
2714          }                                                                                                         
2715      }                                                                                                             
2716                                                                                                                    
2717      /**                                                                                                           
2718       * Event handler for the (Add) Widgets button that appears after a long press                                 
2719       * on the home screen.                                                                                        
2720       */                                                                                                           
2721      protected void onClickAddWidgetButton(View view) {                                                            
2722          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2723          showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                      
2724      }                                                                                                             
2725                                                                                                                    
2726      /**                                                                                                           
2727       * Event handler for the wallpaper picker button that appears after a long press                              
2728       * on the home screen.                                                                                        
2729       */                                                                                                           
2730      protected void onClickWallpaperPicker(View v) {                                                               
2731          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2732          final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2733          pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2734          startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
2735      }                                                                                                             
2736                                                                                                                    
2737      /**                                                                                                           
2738       * Event handler for a click on the settings button that appears after a long press                           
2739       * on the home screen.                                                                                        
2740       */                                                                                                           
2741      protected void onClickSettingsButton(View v) {                                                                
2742          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2743      }                                                                                                             
2744                                                                                                                    
2745      public void onTouchDownAllAppsButton(View v) {                                                                
2746          // Provide the same haptic feedback that the system offers for virtual keys.                              
2747          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2748      }                                                                                                             
2749                                                                                                                    
2750      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2751          // Provide the same haptic feedback that the system offers for virtual keys.                              
2752          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2753      }                                                                                                             
2754                                                                                                                    
2755      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2756          if (mHapticFeedbackTouchListener == null) {                                                               
2757              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2758                  @Override                                                                                         
2759                  public boolean onTouch(View v, MotionEvent event) {                                               
2760                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2761                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2762                      }                                                                                             
2763                      return false;                                                                                 
2764                  }                                                                                                 
2765              };                                                                                                    
2766          }                                                                                                         
2767          return mHapticFeedbackTouchListener;                                                                      
2768      }                                                                                                             
2769                                                                                                                    
2770      public void onDragStarted(View view) {}                                                                       
2771                                                                                                                    
2772      /**                                                                                                           
2773       * Called when the user stops interacting with the launcher.                                                  
2774       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2775       */                                                                                                           
2776      protected void onInteractionEnd() {}                                                                          
2777                                                                                                                    
2778      /**                                                                                                           
2779       * Called when the user starts interacting with the launcher.                                                 
2780       * The possible interactions are:                                                                             
2781       *  - open all apps                                                                                           
2782       *  - reorder an app shortcut, or a widget                                                                    
2783       *  - open the overview mode.                                                                                 
2784       * This is a good time to stop doing things that only make sense                                              
2785       * when the user is on the homescreen and not doing housekeeping.                                             
2786       */                                                                                                           
2787      protected void onInteractionBegin() {}                                                                        
2788                                                                                                                    
2789      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
2790          String packageName = componentName.getPackageName();                                                      
2791          try {                                                                                                     
2792              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2793              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2794              launcherApps.showAppDetailsForProfile(componentName, user);                                           
2795          } catch (SecurityException e) {                                                                           
2796              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2797              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
2798          } catch (ActivityNotFoundException e) {                                                                   
2799              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2800              Log.e(TAG, "Unable to launch settings");                                                              
2801          }                                                                                                         
2802      }                                                                                                             
2803                                                                                                                    
2804      // returns true if the activity was started                                                                   
2805      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
2806              UserHandleCompat user) {                                                                              
2807          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2808              // System applications cannot be installed. For now, show a toast explaining that.                    
2809              // We may give them the option of disabling apps this way.                                            
2810              int messageId = R.string.uninstall_system_app_text;                                                   
2811              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2812              return false;                                                                                         
2813          } else {                                                                                                  
2814              String packageName = componentName.getPackageName();                                                  
2815              String className = componentName.getClassName();                                                      
2816              Intent intent = new Intent(                                                                           
2817                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
2818              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
2819                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
2820              if (user != null) {                                                                                   
2821                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
2822              }                                                                                                     
2823              startActivity(intent);                                                                                
2824              return true;                                                                                          
2825          }                                                                                                         
2826      }                                                                                                             
2827                                                                                                                    
2828      boolean startActivity(View v, Intent intent, Object tag) {                                                    
2829          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2830          try {                                                                                                     
2831              // Only launch using the new animation if the shortcut has not opted out (this is a                   
2832              // private contract between launcher and may be ignored in the future).                               
2833              boolean useLaunchAnimation = (v != null) &&                                                           
2834                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
2835              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2836              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2837                                                                                                                    
2838              UserHandleCompat user = null;                                                                         
2839              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
2840                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
2841                  user = userManager.getUserForSerialNumber(serialNumber);                                          
2842              }                                                                                                     
2843                                                                                                                    
2844              Bundle optsBundle = null;                                                                             
2845              if (useLaunchAnimation) {                                                                             
2846                  ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
2847                          ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       
2848                          ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
2849                  optsBundle = opts.toBundle();                                                                     
2850              }                                                                                                     
2851                                                                                                                    
2852              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
2853                  // Could be launching some bookkeeping activity                                                   
2854                  startActivity(intent, optsBundle);                                                                
2855              } else {                                                                                              
2856                  // TODO Component can be null when shortcuts are supported for secondary user                     
2857                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
2858                          intent.getSourceBounds(), optsBundle);                                                    
2859              }                                                                                                     
2860              return true;                                                                                          
2861          } catch (SecurityException e) {                                                                           
2862              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2863              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
2864                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
2865                      "or use the exported attribute for this activity. "                                           
2866                      + "tag="+ tag + " intent=" + intent, e);                                                      
2867          }                                                                                                         
2868          return false;                                                                                             
2869      }                                                                                                             
2870                                                                                                                    
2871      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
2872          boolean success = false;                                                                                  
2873          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
2874              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
2875              return false;                                                                                         
2876          }                                                                                                         
2877          try {                                                                                                     
2878              success = startActivity(v, intent, tag);                                                              
2879          } catch (ActivityNotFoundException e) {                                                                   
2880              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2881              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
2882          }                                                                                                         
2883          return success;                                                                                           
2884      }                                                                                                             
2885                                                                                                                    
2886      /**                                                                                                           
2887       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
2888       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
2889       */                                                                                                           
2890      private void copyFolderIconToImage(FolderIcon fi) {                                                           
2891          final int width = fi.getMeasuredWidth();                                                                  
2892          final int height = fi.getMeasuredHeight();                                                                
2893                                                                                                                    
2894          // Lazy load ImageView, Bitmap and Canvas                                                                 
2895          if (mFolderIconImageView == null) {                                                                       
2896              mFolderIconImageView = new ImageView(this);                                                           
2897          }                                                                                                         
2898          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
2899                  mFolderIconBitmap.getHeight() != height) {                                                        
2900              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
2901              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
2902          }                                                                                                         
2903                                                                                                                    
2904          DragLayer.LayoutParams lp;                                                                                
2905          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
2906              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
2907          } else {                                                                                                  
2908              lp = new DragLayer.LayoutParams(width, height);                                                       
2909          }                                                                                                         
2910                                                                                                                    
2911          // The layout from which the folder is being opened may be scaled, adjust the starting                    
2912          // view size by this scale factor.                                                                        
2913          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
2914          lp.customPosition = true;                                                                                 
2915          lp.x = mRectForFolderAnimation.left;                                                                      
2916          lp.y = mRectForFolderAnimation.top;                                                                       
2917          lp.width = (int) (scale * width);                                                                         
2918          lp.height = (int) (scale * height);                                                                       
2919                                                                                                                    
2920          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
2921          fi.draw(mFolderIconCanvas);                                                                               
2922          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
2923          if (fi.getFolder() != null) {                                                                             
2924              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
2925              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
2926          }                                                                                                         
2927          // Just in case this image view is still in the drag layer from a previous animation,                     
2928          // we remove it and re-add it.                                                                            
2929          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
2930              mDragLayer.removeView(mFolderIconImageView);                                                          
2931          }                                                                                                         
2932          mDragLayer.addView(mFolderIconImageView, lp);                                                             
2933          if (fi.getFolder() != null) {                                                                             
2934              fi.getFolder().bringToFront();                                                                        
2935          }                                                                                                         
2936      }                                                                                                             
2937                                                                                                                    
2938      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
2939          if (fi == null) return;                                                                                   
2940          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
2941          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
2942          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
2943                                                                                                                    
2944          FolderInfo info = (FolderInfo) fi.getTag();                                                               
2945          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
2946              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
2947              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
2948              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
2949          }                                                                                                         
2950                                                                                                                    
2951          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
2952          copyFolderIconToImage(fi);                                                                                
2953          fi.setVisibility(View.INVISIBLE);                                                                         
2954                                                                                                                    
2955          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
2956                  scaleX, scaleY);                                                                                  
2957          if (Utilities.isLmpOrAbove()) {                                                                           
2958              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
2959          }                                                                                                         
2960          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
2961          oa.start();                                                                                               
2962      }                                                                                                             
2963                                                                                                                    
2964      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
2965          if (fi == null) return;                                                                                   
2966          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
2967          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
2968          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
2969                                                                                                                    
2970          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
2971                                                                                                                    
2972          // We remove and re-draw the FolderIcon in-case it has changed                                            
2973          mDragLayer.removeView(mFolderIconImageView);                                                              
2974          copyFolderIconToImage(fi);                                                                                
2975          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
2976                  scaleX, scaleY);                                                                                  
2977          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
2978          oa.addListener(new AnimatorListenerAdapter() {                                                            
2979              @Override                                                                                             
2980              public void onAnimationEnd(Animator animation) {                                                      
2981                  if (cl != null) {                                                                                 
2982                      cl.clearFolderLeaveBehind();                                                                  
2983                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
2984                      mDragLayer.removeView(mFolderIconImageView);                                                  
2985                      fi.setVisibility(View.VISIBLE);                                                               
2986                  }                                                                                                 
2987              }                                                                                                     
2988          });                                                                                                       
2989          oa.start();                                                                                               
2990      }                                                                                                             
2991                                                                                                                    
2992      /**                                                                                                           
2993       * Opens the user folder described by the specified tag. The opening of the folder                            
2994       * is animated relative to the specified View. If the View is null, no animation                              
2995       * is played.                                                                                                 
2996       *                                                                                                            
2997       * @param folderInfo The FolderInfo describing the folder to open.                                            
2998       */                                                                                                           
2999      public void openFolder(FolderIcon folderIcon) {                                                               
3000          Folder folder = folderIcon.getFolder();                                                                   
3001          FolderInfo info = folder.mInfo;                                                                           
3002                                                                                                                    
3003          info.opened = true;                                                                                       
3004                                                                                                                    
3005          // Just verify that the folder hasn't already been added to the DragLayer.                                
3006          // There was a one-off crash where the folder had a parent already.                                       
3007          if (folder.getParent() == null) {                                                                         
3008              mDragLayer.addView(folder);                                                                           
3009              mDragController.addDropTarget((DropTarget) folder);                                                   
3010          } else {                                                                                                  
3011              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3012                      folder.getParent() + ").");                                                                   
3013          }                                                                                                         
3014          folder.animateOpen();                                                                                     
3015          growAndFadeOutFolderIcon(folderIcon);                                                                     
3016                                                                                                                    
3017          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3018          // the workspace items                                                                                    
3019          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3020          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3021      }                                                                                                             
3022                                                                                                                    
3023      public void closeFolder() {                                                                                   
3024          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3025          if (folder != null) {                                                                                     
3026              if (folder.isEditingName()) {                                                                         
3027                  folder.dismissEditingName();                                                                      
3028              }                                                                                                     
3029              closeFolder(folder);                                                                                  
3030          }                                                                                                         
3031      }                                                                                                             
3032                                                                                                                    
3033      void closeFolder(Folder folder) {                                                                             
3034          folder.getInfo().opened = false;                                                                          
3035                                                                                                                    
3036          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3037          if (parent != null) {                                                                                     
3038              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3039              shrinkAndFadeInFolderIcon(fi);                                                                        
3040          }                                                                                                         
3041          folder.animateClosed();                                                                                   
3042                                                                                                                    
3043          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3044          // longer occludeds the workspace items                                                                   
3045          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3046      }                                                                                                             
3047                                                                                                                    
3048      public boolean onLongClick(View v) {                                                                          
3049          if (!isDraggingEnabled()) return false;                                                                   
3050          if (isWorkspaceLocked()) return false;                                                                    
3051          if (mState != State.WORKSPACE) return false;                                                              
3052                                                                                                                    
3053          if (v instanceof Workspace) {                                                                             
3054              if (!mWorkspace.isInOverviewMode()) {                                                                 
3055                  if (mWorkspace.enterOverviewMode()) {                                                             
3056                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3057                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3058                      return true;                                                                                  
3059                  } else {                                                                                          
3060                      return false;                                                                                 
3061                  }                                                                                                 
3062              } else {                                                                                              
3063                  return false;                                                                                     
3064              }                                                                                                     
3065          }                                                                                                         
3066                                                                                                                    
3067          CellLayout.CellInfo longClickCellInfo = null;                                                             
3068          View itemUnderLongClick = null;                                                                           
3069          if (v.getTag() instanceof ItemInfo) {                                                                     
3070              ItemInfo info = (ItemInfo) v.getTag();                                                                
3071              longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                
3072              itemUnderLongClick = longClickCellInfo.cell;                                                          
3073              resetAddInfo();                                                                                       
3074          }                                                                                                         
3075                                                                                                                    
3076          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3077          // on hotseat items.                                                                                      
3078          final boolean inHotseat = isHotseatLayout(v);                                                             
3079          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3080          if (allowLongPress && !mDragController.isDragging()) {                                                    
3081              if (itemUnderLongClick == null) {                                                                     
3082                  // User long pressed on empty space                                                               
3083                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3084                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3085                  if (mWorkspace.isInOverviewMode()) {                                                              
3086                      mWorkspace.startReordering(v);                                                                
3087                  } else {                                                                                          
3088                      mWorkspace.enterOverviewMode();                                                               
3089                  }                                                                                                 
3090              } else {                                                                                              
3091                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3092                          mHotseat.getOrderInHotseat(                                                               
3093                                  longClickCellInfo.cellX,                                                          
3094                                  longClickCellInfo.cellY));                                                        
3095                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3096                      // User long pressed on an item                                                               
3097                      mWorkspace.startDrag(longClickCellInfo);                                                      
3098                  }                                                                                                 
3099              }                                                                                                     
3100          }                                                                                                         
3101          return true;                                                                                              
3102      }                                                                                                             
3103                                                                                                                    
3104      boolean isHotseatLayout(View layout) {                                                                        
3105          return mHotseat != null && layout != null &&                                                              
3106                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3107      }                                                                                                             
3108                                                                                                                    
3109      /**                                                                                                           
3110       * Returns the CellLayout of the specified container at the specified screen.                                 
3111       */                                                                                                           
3112      CellLayout getCellLayout(long container, long screenId) {                                                     
3113          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3114              if (mHotseat != null) {                                                                               
3115                  return mHotseat.getLayout();                                                                      
3116              } else {                                                                                              
3117                  return null;                                                                                      
3118              }                                                                                                     
3119          } else {                                                                                                  
3120              return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3121          }                                                                                                         
3122      }                                                                                                             
3123                                                                                                                    
3124      public boolean isAllAppsVisible() {                                                                           
3125          return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3126      }                                                                                                             
3127                                                                                                                    
3128      private void setWorkspaceBackground(boolean workspace) {                                                      
3129          mLauncherView.setBackground(workspace ?                                                                   
3130                  mWorkspaceBackgroundDrawable : null);                                                             
3131      }                                                                                                             
3132                                                                                                                    
3133      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3134          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3135          int curflags = getWindow().getAttributes().flags                                                          
3136                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3137          if (wpflags != curflags) {                                                                                
3138              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3139          }                                                                                                         
3140          setWorkspaceBackground(visible);                                                                          
3141      }                                                                                                             
3142                                                                                                                    
3143      private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3144          if (v instanceof LauncherTransitionable) {                                                                
3145              ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3146          }                                                                                                         
3147      }                                                                                                             
3148                                                                                                                    
3149      private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3150          if (v instanceof LauncherTransitionable) {                                                                
3151              ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3152          }                                                                                                         
3153                                                                                                                    
3154          // Update the workspace transition step as well                                                           
3155          dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3156      }                                                                                                             
3157                                                                                                                    
3158      private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3159          if (v instanceof LauncherTransitionable) {                                                                
3160              ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3161          }                                                                                                         
3162      }                                                                                                             
3163                                                                                                                    
3164      private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3165          if (v instanceof LauncherTransitionable) {                                                                
3166              ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3167          }                                                                                                         
3168                                                                                                                    
3169          // Update the workspace transition step as well                                                           
3170          dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3171      }                                                                                                             
3172                                                                                                                    
3173      /**                                                                                                           
3174       * Things to test when changing the following seven functions.                                                
3175       *   - Home from workspace                                                                                    
3176       *          - from center screen                                                                              
3177       *          - from other screens                                                                              
3178       *   - Home from all apps                                                                                     
3179       *          - from center screen                                                                              
3180       *          - from other screens                                                                              
3181       *   - Back from all apps                                                                                     
3182       *          - from center screen                                                                              
3183       *          - from other screens                                                                              
3184       *   - Launch app from workspace and quit                                                                     
3185       *          - with back                                                                                       
3186       *          - with home                                                                                       
3187       *   - Launch app from all apps and quit                                                                      
3188       *          - with back                                                                                       
3189       *          - with home                                                                                       
3190       *   - Go to a screen that's not the default, then all                                                        
3191       *     apps, and launch and app, and go back                                                                  
3192       *          - with back                                                                                       
3193       *          -with home                                                                                        
3194       *   - On workspace, long press power and go back                                                             
3195       *          - with back                                                                                       
3196       *          - with home                                                                                       
3197       *   - On all apps, long press power and go back                                                              
3198       *          - with back                                                                                       
3199       *          - with home                                                                                       
3200       *   - On workspace, power off                                                                                
3201       *   - On all apps, power off                                                                                 
3202       *   - Launch an app and turn off the screen while in that app                                                
3203       *          - Go back with home key                                                                           
3204       *          - Go back with back key  TODO: make this not go to workspace                                      
3205       *          - From all apps                                                                                   
3206       *          - From workspace                                                                                  
3207       *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3208       *          - From all apps                                                                                   
3209       *          - From the center workspace                                                                       
3210       *          - From another workspace                                                                          
3211       */                                                                                                           
3212                                                                                                                    
3213      /**                                                                                                           
3214       * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3215       * Assumes that the view to show is anchored at either the very top or very bottom                            
3216       * of the screen.                                                                                             
3217       */                                                                                                           
3218      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3219          AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3220          showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3221      }                                                                                                             
3222                                                                                                                    
3223      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3224                                           final AppsCustomizePagedView.ContentType contentType) {                  
3225          if (mStateAnimation != null) {                                                                            
3226              mStateAnimation.setDuration(0);                                                                       
3227              mStateAnimation.cancel();                                                                             
3228              mStateAnimation = null;                                                                               
3229          }                                                                                                         
3230                                                                                                                    
3231          boolean material = Utilities.isLmpOrAbove();                                                              
3232                                                                                                                    
3233          final Resources res = getResources();                                                                     
3234                                                                                                                    
3235          final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                            
3236          final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);                        
3237          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3238          final int itemsAlphaStagger =                                                                             
3239                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3240                                                                                                                    
3241          final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                
3242          final View fromView = mWorkspace;                                                                         
3243          final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3244                                                                                                                    
3245          final ArrayList<View> layerViews = new ArrayList<View>();                                                 
3246                                                                                                                    
3247          Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3248                  Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3249          Animator workspaceAnim =                                                                                  
3250                  mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3251          if (!LauncherAppState.isDisableAllApps()                                                                  
3252                  || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3253              // Set the content type for the all apps/widgets space                                                
3254              mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3255          }                                                                                                         
3256                                                                                                                    
3257          // If for some reason our views aren't initialized, don't animate                                         
3258          boolean initialized = getAllAppsButton() != null;                                                         
3259                                                                                                                    
3260          if (animated && initialized) {                                                                            
3261              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3262              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3263                      toView.findViewById(R.id.apps_customize_pane_content);                                        
3264                                                                                                                    
3265              final View page = content.getPageAt(content.getCurrentPage());                                        
3266              final View revealView = toView.findViewById(R.id.fake_page);                                          
3267                                                                                                                    
3268              final float initialPanelAlpha = 1f;                                                                   
3269                                                                                                                    
3270              final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3271              if (isWidgetTray) {                                                                                   
3272                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3273              } else {                                                                                              
3274                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3275              }                                                                                                     
3276                                                                                                                    
3277              // Hide the real page background, and swap in the fake one                                            
3278              content.setPageBackgroundsVisible(false);                                                             
3279              revealView.setVisibility(View.VISIBLE);                                                               
3280              // We need to hide this view as the animation start will be posted.                                   
3281              revealView.setAlpha(0);                                                                               
3282                                                                                                                    
3283              int width = revealView.getMeasuredWidth();                                                            
3284              int height = revealView.getMeasuredHeight();                                                          
3285              float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3286                                                                                                                    
3287              revealView.setTranslationY(0);                                                                        
3288              revealView.setTranslationX(0);                                                                        
3289                                                                                                                    
3290              // Get the y delta between the center of the page and the center of the all apps button               
3291              int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3292                      getAllAppsButton(), null);                                                                    
3293                                                                                                                    
3294              float alpha = 0;                                                                                      
3295              float xDrift = 0;                                                                                     
3296              float yDrift = 0;                                                                                     
3297              if (material) {                                                                                       
3298                  alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3299                  yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3300                  xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3301              } else {                                                                                              
3302                  yDrift = 2 * height / 3;                                                                          
3303                  xDrift = 0;                                                                                       
3304              }                                                                                                     
3305              final float initAlpha = alpha;                                                                        
3306                                                                                                                    
3307              revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                              
3308              layerViews.add(revealView);                                                                           
3309              PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3310              PropertyValuesHolder panelDriftY =                                                                    
3311                      PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3312              PropertyValuesHolder panelDriftX =                                                                    
3313                      PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3314                                                                                                                    
3315              ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3316                      panelAlpha, panelDriftY, panelDriftX);                                                        
3317                                                                                                                    
3318              panelAlphaAndDrift.setDuration(revealDuration);                                                       
3319              panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3320                                                                                                                    
3321              mStateAnimation.play(panelAlphaAndDrift);                                                             
3322                                                                                                                    
3323              if (page != null) {                                                                                   
3324                  page.setVisibility(View.VISIBLE);                                                                 
3325                  page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                                
3326                  layerViews.add(page);                                                                             
3327                                                                                                                    
3328                  ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3329                  page.setTranslationY(yDrift);                                                                     
3330                  pageDrift.setDuration(revealDuration);                                                            
3331                  pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3332                  pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3333                  mStateAnimation.play(pageDrift);                                                                  
3334                                                                                                                    
3335                  page.setAlpha(0f);                                                                                
3336                  ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3337                  itemsAlpha.setDuration(revealDuration);                                                           
3338                  itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3339                  itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3340                  mStateAnimation.play(itemsAlpha);                                                                 
3341              }                                                                                                     
3342                                                                                                                    
3343              View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3344              pageIndicators.setAlpha(0.01f);                                                                       
3345              ObjectAnimator indicatorsAlpha =                                                                      
3346                      ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3347              indicatorsAlpha.setDuration(revealDuration);                                                          
3348              mStateAnimation.play(indicatorsAlpha);                                                                
3349                                                                                                                    
3350              if (material) {                                                                                       
3351                  final View allApps = getAllAppsButton();                                                          
3352                  int allAppsButtonSize = LauncherAppState.getInstance().                                           
3353                          getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3354                  float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3355                  Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3356                                  height / 2, startRadius, revealRadius);                                           
3357                  reveal.setDuration(revealDuration);                                                               
3358                  reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3359                                                                                                                    
3360                  reveal.addListener(new AnimatorListenerAdapter() {                                                
3361                      public void onAnimationStart(Animator animation) {                                            
3362                          if (!isWidgetTray) {                                                                      
3363                              allApps.setVisibility(View.INVISIBLE);                                                
3364                          }                                                                                         
3365                      }                                                                                             
3366                      public void onAnimationEnd(Animator animation) {                                              
3367                          if (!isWidgetTray) {                                                                      
3368                              allApps.setVisibility(View.VISIBLE);                                                  
3369                          }                                                                                         
3370                      }                                                                                             
3371                  });                                                                                               
3372                  mStateAnimation.play(reveal);                                                                     
3373              }                                                                                                     
3374                                                                                                                    
3375              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3376                  @Override                                                                                         
3377                  public void onAnimationEnd(Animator animation) {                                                  
3378                      dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3379                      dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3380                                                                                                                    
3381                      revealView.setVisibility(View.INVISIBLE);                                                     
3382                      revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                          
3383                      if (page != null) {                                                                           
3384                          page.setLayerType(View.LAYER_TYPE_NONE, null);                                            
3385                      }                                                                                             
3386                      content.setPageBackgroundsVisible(true);                                                      
3387                                                                                                                    
3388                      // Hide the search bar                                                                        
3389                      if (mSearchDropTargetBar != null) {                                                           
3390                          mSearchDropTargetBar.hideSearchBar(false);                                                
3391                      }                                                                                             
3392                  }                                                                                                 
3393                                                                                                                    
3394              });                                                                                                   
3395                                                                                                                    
3396              if (workspaceAnim != null) {                                                                          
3397                  mStateAnimation.play(workspaceAnim);                                                              
3398              }                                                                                                     
3399                                                                                                                    
3400              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3401              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3402              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3403              final Runnable startAnimRunnable = new Runnable() {                                                   
3404                  public void run() {                                                                               
3405                      // Check that mStateAnimation hasn't changed while                                            
3406                      // we waited for a layout/draw pass                                                           
3407                      if (mStateAnimation != stateAnimation)                                                        
3408                          return;                                                                                   
3409                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3410                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3411                                                                                                                    
3412                      revealView.setAlpha(initAlpha);                                                               
3413                      if (Utilities.isLmpOrAbove()) {                                                               
3414                          for (int i = 0; i < layerViews.size(); i++) {                                             
3415                              View v = layerViews.get(i);                                                           
3416                              if (v != null) {                                                                      
3417                                  boolean attached = true;                                                          
3418                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                        
3419                                      attached = v.isAttachedToWindow();                                            
3420                                  }                                                                                 
3421                                  if (attached) v.buildLayer();                                                     
3422                              }                                                                                     
3423                          }                                                                                         
3424                      }                                                                                             
3425                      mStateAnimation.start();                                                                      
3426                  }                                                                                                 
3427              };                                                                                                    
3428              toView.bringToFront();                                                                                
3429              toView.setVisibility(View.VISIBLE);                                                                   
3430              toView.post(startAnimRunnable);                                                                       
3431          } else {                                                                                                  
3432              toView.setTranslationX(0.0f);                                                                         
3433              toView.setTranslationY(0.0f);                                                                         
3434              toView.setScaleX(1.0f);                                                                               
3435              toView.setScaleY(1.0f);                                                                               
3436              toView.setVisibility(View.VISIBLE);                                                                   
3437              toView.bringToFront();                                                                                
3438                                                                                                                    
3439              if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3440                  // Hide the search bar                                                                            
3441                  if (mSearchDropTargetBar != null) {                                                               
3442                      mSearchDropTargetBar.hideSearchBar(false);                                                    
3443                  }                                                                                                 
3444              }                                                                                                     
3445              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3446              dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3447              dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3448              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3449              dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3450              dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3451          }                                                                                                         
3452      }                                                                                                             
3453                                                                                                                    
3454      /**                                                                                                           
3455       * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3456       * This is the opposite of showAppsCustomizeHelper.                                                           
3457       * @param animated If true, the transition will be animated.                                                  
3458       */                                                                                                           
3459      private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3460              final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3461                                                                                                                    
3462          if (mStateAnimation != null) {                                                                            
3463              mStateAnimation.setDuration(0);                                                                       
3464              mStateAnimation.cancel();                                                                             
3465              mStateAnimation = null;                                                                               
3466          }                                                                                                         
3467                                                                                                                    
3468          boolean material = Utilities.isLmpOrAbove();                                                              
3469          Resources res = getResources();                                                                           
3470                                                                                                                    
3471          final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                           
3472          final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);                    
3473          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3474          final int itemsAlphaStagger =                                                                             
3475                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3476                                                                                                                    
3477          final float scaleFactor = (float)                                                                         
3478                  res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                                    
3479          final View fromView = mAppsCustomizeTabHost;                                                              
3480          final View toView = mWorkspace;                                                                           
3481          Animator workspaceAnim = null;                                                                            
3482          final ArrayList<View> layerViews = new ArrayList<View>();                                                 
3483                                                                                                                    
3484          if (toState == Workspace.State.NORMAL) {                                                                  
3485              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3486                      toState, animated, layerViews);                                                               
3487          } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3488                  toState == Workspace.State.OVERVIEW) {                                                            
3489              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3490                      toState, animated, layerViews);                                                               
3491          }                                                                                                         
3492                                                                                                                    
3493          // If for some reason our views aren't initialized, don't animate                                         
3494          boolean initialized = getAllAppsButton() != null;                                                         
3495                                                                                                                    
3496          if (animated && initialized) {                                                                            
3497              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3498              if (workspaceAnim != null) {                                                                          
3499                  mStateAnimation.play(workspaceAnim);                                                              
3500              }                                                                                                     
3501                                                                                                                    
3502              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3503                      fromView.findViewById(R.id.apps_customize_pane_content);                                      
3504                                                                                                                    
3505              final View page = content.getPageAt(content.getNextPage());                                           
3506                                                                                                                    
3507              // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3508              int count = content.getChildCount();                                                                  
3509              for (int i = 0; i < count; i++) {                                                                     
3510                  View child = content.getChildAt(i);                                                               
3511                  if (child != page) {                                                                              
3512                      child.setVisibility(View.INVISIBLE);                                                          
3513                  }                                                                                                 
3514              }                                                                                                     
3515              final View revealView = fromView.findViewById(R.id.fake_page);                                        
3516                                                                                                                    
3517              // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3518              // don't perform all these no-op animations. In particularly, this was causing                        
3519              // the all-apps button to pop in and out.                                                             
3520              if (fromView.getVisibility() == View.VISIBLE) {                                                       
3521                  AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3522                  final boolean isWidgetTray =                                                                      
3523                          contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3524                                                                                                                    
3525                  if (isWidgetTray) {                                                                               
3526                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3527                  } else {                                                                                          
3528                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3529                  }                                                                                                 
3530                                                                                                                    
3531                  int width = revealView.getMeasuredWidth();                                                        
3532                  int height = revealView.getMeasuredHeight();                                                      
3533                  float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3534                                                                                                                    
3535                  // Hide the real page background, and swap in the fake one                                        
3536                  revealView.setVisibility(View.VISIBLE);                                                           
3537                  content.setPageBackgroundsVisible(false);                                                         
3538                                                                                                                    
3539                  final View allAppsButton = getAllAppsButton();                                                    
3540                  revealView.setTranslationY(0);                                                                    
3541                  int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3542                          allAppsButton, null);                                                                     
3543                                                                                                                    
3544                  float xDrift = 0;                                                                                 
3545                  float yDrift = 0;                                                                                 
3546                  if (material) {                                                                                   
3547                      yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3548                      xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3549                  } else {                                                                                          
3550                      yDrift = 5 * height / 4;                                                                      
3551                      xDrift = 0;                                                                                   
3552                  }                                                                                                 
3553                                                                                                                    
3554                  revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                          
3555                  TimeInterpolator decelerateInterpolator = material ?                                              
3556                          new LogDecelerateInterpolator(100, 0) :                                                   
3557                          new LogDecelerateInterpolator(30, 0);                                                     
3558                                                                                                                    
3559                  // The vertical motion of the apps panel should be delayed by one frame                           
3560                  // from the conceal animation in order to give the right feel. We correpsondingly                 
3561                  // shorten the duration so that the slide and conceal end at the same time.                       
3562                  ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3563                          0, yDrift);                                                                               
3564                  panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3565                  panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3566                  panelDriftY.setInterpolator(decelerateInterpolator);                                              
3567                  mStateAnimation.play(panelDriftY);                                                                
3568                                                                                                                    
3569                  ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3570                          0, xDrift);                                                                               
3571                  panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3572                  panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3573                  panelDriftX.setInterpolator(decelerateInterpolator);                                              
3574                  mStateAnimation.play(panelDriftX);                                                                
3575                                                                                                                    
3576                  if (isWidgetTray || !material) {                                                                  
3577                      float finalAlpha = material ? 0.4f : 0f;                                                      
3578                      revealView.setAlpha(1f);                                                                      
3579                      ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3580                              1f, finalAlpha);                                                                      
3581                      panelAlpha.setDuration(revealDuration);                                                       
3582                      panelAlpha.setInterpolator(material ? decelerateInterpolator :                                
3583                          new AccelerateInterpolator(1.5f));                                                        
3584                      mStateAnimation.play(panelAlpha);                                                             
3585                  }                                                                                                 
3586                                                                                                                    
3587                  if (page != null) {                                                                               
3588                      page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                            
3589                                                                                                                    
3590                      ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3591                              0, yDrift);                                                                           
3592                      page.setTranslationY(0);                                                                      
3593                      pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3594                      pageDrift.setInterpolator(decelerateInterpolator);                                            
3595                      pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3596                      mStateAnimation.play(pageDrift);                                                              
3597                                                                                                                    
3598                      page.setAlpha(1f);                                                                            
3599                      ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3600                      itemsAlpha.setDuration(100);                                                                  
3601                      itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3602                      mStateAnimation.play(itemsAlpha);                                                             
3603                  }                                                                                                 
3604                                                                                                                    
3605                  View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3606                  pageIndicators.setAlpha(1f);                                                                      
3607                  ObjectAnimator indicatorsAlpha =                                                                  
3608                          LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3609                  indicatorsAlpha.setDuration(revealDuration);                                                      
3610                  indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3611                  mStateAnimation.play(indicatorsAlpha);                                                            
3612                                                                                                                    
3613                  width = revealView.getMeasuredWidth();                                                            
3614                                                                                                                    
3615                  if (material) {                                                                                   
3616                      if (!isWidgetTray) {                                                                          
3617                          allAppsButton.setVisibility(View.INVISIBLE);                                              
3618                      }                                                                                             
3619                      int allAppsButtonSize = LauncherAppState.getInstance().                                       
3620                              getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3621                      float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3622                      Animator reveal =                                                                             
3623                              LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3624                                      height / 2, revealRadius, finalRadius);                                       
3625                      reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3626                      reveal.setDuration(revealDuration);                                                           
3627                      reveal.setStartDelay(itemsAlphaStagger);                                                      
3628                                                                                                                    
3629                      reveal.addListener(new AnimatorListenerAdapter() {                                            
3630                          public void onAnimationEnd(Animator animation) {                                          
3631                              revealView.setVisibility(View.INVISIBLE);                                             
3632                              if (!isWidgetTray) {                                                                  
3633                                  allAppsButton.setVisibility(View.VISIBLE);                                        
3634                              }                                                                                     
3635                          }                                                                                         
3636                      });                                                                                           
3637                                                                                                                    
3638                      mStateAnimation.play(reveal);                                                                 
3639                  }                                                                                                 
3640                                                                                                                    
3641                  dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3642                  dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3643                  mAppsCustomizeContent.stopScrolling();                                                            
3644              }                                                                                                     
3645                                                                                                                    
3646              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3647                  @Override                                                                                         
3648                  public void onAnimationEnd(Animator animation) {                                                  
3649                      fromView.setVisibility(View.GONE);                                                            
3650                      dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3651                      dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3652                      if (onCompleteRunnable != null) {                                                             
3653                          onCompleteRunnable.run();                                                                 
3654                      }                                                                                             
3655                                                                                                                    
3656                      revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                          
3657                      if (page != null) {                                                                           
3658                          page.setLayerType(View.LAYER_TYPE_NONE, null);                                            
3659                      }                                                                                             
3660                      content.setPageBackgroundsVisible(true);                                                      
3661                      // Unhide side pages                                                                          
3662                      int count = content.getChildCount();                                                          
3663                      for (int i = 0; i < count; i++) {                                                             
3664                          View child = content.getChildAt(i);                                                       
3665                          child.setVisibility(View.VISIBLE);                                                        
3666                      }                                                                                             
3667                                                                                                                    
3668                      // Reset page transforms                                                                      
3669                      if (page != null) {                                                                           
3670                          page.setTranslationX(0);                                                                  
3671                          page.setTranslationY(0);                                                                  
3672                          page.setAlpha(1);                                                                         
3673                      }                                                                                             
3674                      content.setCurrentPage(content.getNextPage());                                                
3675                                                                                                                    
3676                      mAppsCustomizeContent.updateCurrentPageScroll();                                              
3677                  }                                                                                                 
3678              });                                                                                                   
3679                                                                                                                    
3680              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3681              final Runnable startAnimRunnable = new Runnable() {                                                   
3682                  public void run() {                                                                               
3683                      // Check that mStateAnimation hasn't changed while                                            
3684                      // we waited for a layout/draw pass                                                           
3685                      if (mStateAnimation != stateAnimation)                                                        
3686                          return;                                                                                   
3687                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3688                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3689                                                                                                                    
3690                      if (Utilities.isLmpOrAbove()) {                                                               
3691                          for (int i = 0; i < layerViews.size(); i++) {                                             
3692                              View v = layerViews.get(i);                                                           
3693                              if (v != null) {                                                                      
3694                                  boolean attached = true;                                                          
3695                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                        
3696                                      attached = v.isAttachedToWindow();                                            
3697                                  }                                                                                 
3698                                  if (attached) v.buildLayer();                                                     
3699                              }                                                                                     
3700                          }                                                                                         
3701                      }                                                                                             
3702                      mStateAnimation.start();                                                                      
3703                  }                                                                                                 
3704              };                                                                                                    
3705              fromView.post(startAnimRunnable);                                                                     
3706          } else {                                                                                                  
3707              fromView.setVisibility(View.GONE);                                                                    
3708              dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
3709              dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
3710              dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
3711              dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
3712              dispatchOnLauncherTransitionStart(toView, animated, true);                                            
3713              dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
3714          }                                                                                                         
3715      }                                                                                                             
3716                                                                                                                    
3717      @Override                                                                                                     
3718      public void onTrimMemory(int level) {                                                                         
3719          super.onTrimMemory(level);                                                                                
3720          if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                                  
3721              mAppsCustomizeTabHost.onTrimMemory();                                                                 
3722          }                                                                                                         
3723      }                                                                                                             
3724                                                                                                                    
3725      protected void showWorkspace(boolean animated) {                                                              
3726          showWorkspace(animated, null);                                                                            
3727      }                                                                                                             
3728                                                                                                                    
3729      protected void showWorkspace() {                                                                              
3730          showWorkspace(true);                                                                                      
3731      }                                                                                                             
3732                                                                                                                    
3733      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
3734          if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
3735              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
3736              mWorkspace.setVisibility(View.VISIBLE);                                                               
3737              hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 
3738                                                                                                                    
3739              // Show the search bar (only animate if we were showing the drop target bar in spring                 
3740              // loaded mode)                                                                                       
3741              if (mSearchDropTargetBar != null) {                                                                   
3742                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
3743              }                                                                                                     
3744                                                                                                                    
3745              // Set focus to the AppsCustomize button                                                              
3746              if (mAllAppsButton != null) {                                                                         
3747                  mAllAppsButton.requestFocus();                                                                    
3748              }                                                                                                     
3749          }                                                                                                         
3750                                                                                                                    
3751          // Change the state *after* we've called all the transition code                                          
3752          mState = State.WORKSPACE;                                                                                 
3753                                                                                                                    
3754          // Resume the auto-advance of widgets                                                                     
3755          mUserPresent = true;                                                                                      
3756          updateRunning();                                                                                          
3757                                                                                                                    
3758          // Send an accessibility event to announce the context change                                             
3759          getWindow().getDecorView()                                                                                
3760                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3761                                                                                                                    
3762          onWorkspaceShown(animated);                                                                               
3763      }                                                                                                             
3764                                                                                                                    
3765      void showOverviewMode(boolean animated) {                                                                     
3766          mWorkspace.setVisibility(View.VISIBLE);                                                                   
3767          hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
3768          mState = State.WORKSPACE;                                                                                 
3769          onWorkspaceShown(animated);                                                                               
3770      }                                                                                                             
3771                                                                                                                    
3772      public void onWorkspaceShown(boolean animated) {                                                              
3773      }                                                                                                             
3774                                                                                                                    
3775      void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
3776                       boolean resetPageToZero) {                                                                   
3777          if (mState != State.WORKSPACE) return;                                                                    
3778                                                                                                                    
3779          if (resetPageToZero) {                                                                                    
3780              mAppsCustomizeTabHost.reset();                                                                        
3781          }                                                                                                         
3782          showAppsCustomizeHelper(animated, false, contentType);                                                    
3783          mAppsCustomizeTabHost.post(new Runnable() {                                                               
3784              @Override                                                                                             
3785              public void run() {                                                                                   
3786                  // We post this in-case the all apps view isn't yet constructed.                                  
3787                  mAppsCustomizeTabHost.requestFocus();                                                             
3788              }                                                                                                     
3789          });                                                                                                       
3790                                                                                                                    
3791          // Change the state *after* we've called all the transition code                                          
3792          mState = State.APPS_CUSTOMIZE;                                                                            
3793                                                                                                                    
3794          // Pause the auto-advance of widgets until we are out of AllApps                                          
3795          mUserPresent = false;                                                                                     
3796          updateRunning();                                                                                          
3797          closeFolder();                                                                                            
3798                                                                                                                    
3799          // Send an accessibility event to announce the context change                                             
3800          getWindow().getDecorView()                                                                                
3801                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3802      }                                                                                                             
3803                                                                                                                    
3804      void enterSpringLoadedDragMode() {                                                                            
3805          if (isAllAppsVisible()) {                                                                                 
3806              hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
3807              mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
3808          }                                                                                                         
3809      }                                                                                                             
3810                                                                                                                    
3811      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
3812              final Runnable onCompleteRunnable) {                                                                  
3813          if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 
3814                                                                                                                    
3815          mHandler.postDelayed(new Runnable() {                                                                     
3816              @Override                                                                                             
3817              public void run() {                                                                                   
3818                  if (successfulDrop) {                                                                             
3819                      // Before we show workspace, hide all apps again because                                      
3820                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
3821                      // clean up our state transition functions                                                    
3822                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
3823                      showWorkspace(true, onCompleteRunnable);                                                      
3824                  } else {                                                                                          
3825                      exitSpringLoadedDragMode();                                                                   
3826                  }                                                                                                 
3827              }                                                                                                     
3828          }, delay);                                                                                                
3829      }                                                                                                             
3830                                                                                                                    
3831      void exitSpringLoadedDragMode() {                                                                             
3832          if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
3833              final boolean animated = true;                                                                        
3834              final boolean springLoaded = true;                                                                    
3835              showAppsCustomizeHelper(animated, springLoaded);                                                      
3836              mState = State.APPS_CUSTOMIZE;                                                                        
3837          }                                                                                                         
3838          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
3839      }                                                                                                             
3840                                                                                                                    
3841      void lockAllApps() {                                                                                          
3842          // TODO                                                                                                   
3843      }                                                                                                             
3844                                                                                                                    
3845      void unlockAllApps() {                                                                                        
3846          // TODO                                                                                                   
3847      }                                                                                                             
3848                                                                                                                    
3849      /**                                                                                                           
3850       * Hides the hotseat area.                                                                                    
3851       */                                                                                                           
3852      void hideHotseat(boolean animated) {                                                                          
3853          if (!LauncherAppState.getInstance().isScreenLarge()) {                                                    
3854              if (animated) {                                                                                       
3855                  if (mHotseat.getAlpha() != 0f) {                                                                  
3856                      int duration = 0;                                                                             
3857                      if (mSearchDropTargetBar != null) {                                                           
3858                          duration = mSearchDropTargetBar.getTransitionOutDuration();                               
3859                      }                                                                                             
3860                      mHotseat.animate().alpha(0f).setDuration(duration);                                           
3861                  }                                                                                                 
3862              } else {                                                                                              
3863                  mHotseat.setAlpha(0f);                                                                            
3864              }                                                                                                     
3865          }                                                                                                         
3866      }                                                                                                             
3867                                                                                                                    
3868      /**                                                                                                           
3869       * Add an item from all apps or customize onto the given workspace screen.                                    
3870       * If layout is null, add to the current screen.                                                              
3871       */                                                                                                           
3872      void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                                    
3873          if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                              
3874              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
3875          }                                                                                                         
3876      }                                                                                                             
3877                                                                                                                    
3878      /** Maps the current orientation to an index for referencing orientation correct global icons */              
3879      private int getCurrentOrientationIndexForGlobalIcons() {                                                      
3880          // default - 0, landscape - 1                                                                             
3881          switch (getResources().getConfiguration().orientation) {                                                  
3882          case Configuration.ORIENTATION_LANDSCAPE:                                                                 
3883              return 1;                                                                                             
3884          default:                                                                                                  
3885              return 0;                                                                                             
3886          }                                                                                                         
3887      }                                                                                                             
3888                                                                                                                    
3889      private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {             
3890          try {                                                                                                     
3891              PackageManager packageManager = getPackageManager();                                                  
3892              // Look for the toolbar icon specified in the activity meta-data                                      
3893              Bundle metaData = packageManager.getActivityInfo(                                                     
3894                      activityName, PackageManager.GET_META_DATA).metaData;                                         
3895              if (metaData != null) {                                                                               
3896                  int iconResId = metaData.getInt(resourceName);                                                    
3897                  if (iconResId != 0) {                                                                             
3898                      Resources res = packageManager.getResourcesForActivity(activityName);                         
3899                      return res.getDrawable(iconResId);                                                            
3900                  }                                                                                                 
3901              }                                                                                                     
3902          } catch (NameNotFoundException e) {                                                                       
3903              // This can happen if the activity defines an invalid drawable                                        
3904              Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +                    
3905                      " not found", e);                                                                             
3906          } catch (Resources.NotFoundException nfe) {                                                               
3907              // This can happen if the activity defines an invalid drawable                                        
3908              Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),                 
3909                      nfe);                                                                                         
3910          }                                                                                                         
3911          return null;                                                                                              
3912      }                                                                                                             
3913                                                                                                                    
3914      // if successful in getting icon, return it; otherwise, set button to use default drawable                    
3915      private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                                  
3916              int buttonId, ComponentName activityName, int fallbackDrawableId,                                     
3917              String toolbarResourceName) {                                                                         
3918          Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);                  
3919          Resources r = getResources();                                                                             
3920          int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                                     
3921          int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                                    
3922                                                                                                                    
3923          TextView button = (TextView) findViewById(buttonId);                                                      
3924          // If we were unable to find the icon via the meta-data, use a generic one                                
3925          if (toolbarIcon == null) {                                                                                
3926              toolbarIcon = r.getDrawable(fallbackDrawableId);                                                      
3927              toolbarIcon.setBounds(0, 0, w, h);                                                                    
3928              if (button != null) {                                                                                 
3929                  button.setCompoundDrawables(toolbarIcon, null, null, null);                                       
3930              }                                                                                                     
3931              return null;                                                                                          
3932          } else {                                                                                                  
3933              toolbarIcon.setBounds(0, 0, w, h);                                                                    
3934              if (button != null) {                                                                                 
3935                  button.setCompoundDrawables(toolbarIcon, null, null, null);                                       
3936              }                                                                                                     
3937              return toolbarIcon.getConstantState();                                                                
3938          }                                                                                                         
3939      }                                                                                                             
3940                                                                                                                    
3941      // if successful in getting icon, return it; otherwise, set button to use default drawable                    
3942      private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                                      
3943              int buttonId, ComponentName activityName, int fallbackDrawableId,                                     
3944              String toolbarResourceName) {                                                                         
3945          ImageView button = (ImageView) findViewById(buttonId);                                                    
3946          Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);                  
3947                                                                                                                    
3948          if (button != null) {                                                                                     
3949              // If we were unable to find the icon via the meta-data, use a                                        
3950              // generic one                                                                                        
3951              if (toolbarIcon == null) {                                                                            
3952                  button.setImageResource(fallbackDrawableId);                                                      
3953              } else {                                                                                              
3954                  button.setImageDrawable(toolbarIcon);                                                             
3955              }                                                                                                     
3956          }                                                                                                         
3957                                                                                                                    
3958          return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                                       
3959                                                                                                                    
3960      }                                                                                                             
3961                                                                                                                    
3962      private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                         
3963          TextView button = (TextView) findViewById(buttonId);                                                      
3964          button.setCompoundDrawables(d, null, null, null);                                                         
3965      }                                                                                                             
3966                                                                                                                    
3967      private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                               
3968          ImageView button = (ImageView) findViewById(buttonId);                                                    
3969          button.setImageDrawable(d.newDrawable(getResources()));                                                   
3970      }                                                                                                             
3971                                                                                                                    
3972      private void invalidatePressedFocusedStates(View container, View button) {                                    
3973          if (container instanceof HolographicLinearLayout) {                                                       
3974              HolographicLinearLayout layout = (HolographicLinearLayout) container;                                 
3975              layout.invalidatePressedFocusedStates();                                                              
3976          } else if (button instanceof HolographicImageView) {                                                      
3977              HolographicImageView view = (HolographicImageView) button;                                            
3978              view.invalidatePressedFocusedStates();                                                                
3979          }                                                                                                         
3980      }                                                                                                             
3981                                                                                                                    
3982      public View getQsbBar() {                                                                                     
3983          if (mQsb == null) {                                                                                       
3984              mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                                  
3985              mSearchDropTargetBar.addView(mQsb);                                                                   
3986          }                                                                                                         
3987          return mQsb;                                                                                              
3988      }                                                                                                             
3989                                                                                                                    
3990      protected boolean updateGlobalSearchIcon() {                                                                  
3991          final View searchButtonContainer = findViewById(R.id.search_button_container);                            
3992          final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                              
3993          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
3994          final View voiceButton = findViewById(R.id.voice_button);                                                 
3995                                                                                                                    
3996          final SearchManager searchManager =                                                                       
3997                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                         
3998          ComponentName activityName = searchManager.getGlobalSearchActivity();                                     
3999          if (activityName != null) {                                                                               
4000              int coi = getCurrentOrientationIndexForGlobalIcons();                                                 
4001              sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                    
4002                      R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,                      
4003                      TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                           
4004              if (sGlobalSearchIcon[coi] == null) {                                                                 
4005                  sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                
4006                          R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,                  
4007                          TOOLBAR_ICON_METADATA_NAME);                                                              
4008              }                                                                                                     
4009                                                                                                                    
4010              if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);                 
4011              searchButton.setVisibility(View.VISIBLE);                                                             
4012              invalidatePressedFocusedStates(searchButtonContainer, searchButton);                                  
4013              return true;                                                                                          
4014          } else {                                                                                                  
4015              // We disable both search and voice search when there is no global search provider                    
4016              if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);                    
4017              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);                      
4018              if (searchButton != null) searchButton.setVisibility(View.GONE);                                      
4019              if (voiceButton != null) voiceButton.setVisibility(View.GONE);                                        
4020              updateVoiceButtonProxyVisible(false);                                                                 
4021              return false;                                                                                         
4022          }                                                                                                         
4023      }                                                                                                             
4024                                                                                                                    
4025      protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                             
4026          final View searchButtonContainer = findViewById(R.id.search_button_container);                            
4027          final View searchButton = (ImageView) findViewById(R.id.search_button);                                   
4028          updateButtonWithDrawable(R.id.search_button, d);                                                          
4029          invalidatePressedFocusedStates(searchButtonContainer, searchButton);                                      
4030      }                                                                                                             
4031                                                                                                                    
4032      protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                              
4033          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4034          final View voiceButton = findViewById(R.id.voice_button);                                                 
4035                                                                                                                    
4036          // We only show/update the voice search icon if the search icon is enabled as well                        
4037          final SearchManager searchManager =                                                                       
4038                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                         
4039          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
4040                                                                                                                    
4041          ComponentName activityName = null;                                                                        
4042          if (globalSearchActivity != null) {                                                                       
4043              // Check if the global search activity handles voice search                                           
4044              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
4045              intent.setPackage(globalSearchActivity.getPackageName());                                             
4046              activityName = intent.resolveActivity(getPackageManager());                                           
4047          }                                                                                                         
4048                                                                                                                    
4049          if (activityName == null) {                                                                               
4050              // Fallback: check if an activity other than the global search activity                               
4051              // resolves this                                                                                      
4052              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
4053              activityName = intent.resolveActivity(getPackageManager());                                           
4054          }                                                                                                         
4055          if (searchVisible && activityName != null) {                                                              
4056              int coi = getCurrentOrientationIndexForGlobalIcons();                                                 
4057              sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                     
4058                      R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,                        
4059                      TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                                     
4060              if (sVoiceSearchIcon[coi] == null) {                                                                  
4061                  sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                 
4062                          R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,                    
4063                          TOOLBAR_ICON_METADATA_NAME);                                                              
4064              }                                                                                                     
4065              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);                   
4066              voiceButton.setVisibility(View.VISIBLE);                                                              
4067              updateVoiceButtonProxyVisible(false);                                                                 
4068              invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                                    
4069              return true;                                                                                          
4070          } else {                                                                                                  
4071              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);                      
4072              if (voiceButton != null) voiceButton.setVisibility(View.GONE);                                        
4073              updateVoiceButtonProxyVisible(false);                                                                 
4074              return false;                                                                                         
4075          }                                                                                                         
4076      }                                                                                                             
4077                                                                                                                    
4078      protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                              
4079          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4080          final View voiceButton = findViewById(R.id.voice_button);                                                 
4081          updateButtonWithDrawable(R.id.voice_button, d);                                                           
4082          invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                                        
4083      }                                                                                                             
4084                                                                                                                    
4085      public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                             
4086          final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                                      
4087          if (voiceButtonProxy != null) {                                                                           
4088              boolean visible = !forceDisableVoiceButtonProxy &&                                                    
4089                      mWorkspace.shouldVoiceButtonProxyBeVisible();                                                 
4090              voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                                   
4091              voiceButtonProxy.bringToFront();                                                                      
4092          }                                                                                                         
4093      }                                                                                                             
4094                                                                                                                    
4095      /**                                                                                                           
4096       * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button proxy   
4097       * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                               
4098       */                                                                                                           
4099      public void disableVoiceButtonProxy(boolean disabled) {                                                       
4100          updateVoiceButtonProxyVisible(disabled);                                                                  
4101      }                                                                                                             
4102                                                                                                                    
4103      @Override                                                                                                     
4104      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4105          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4106          final List<CharSequence> text = event.getText();                                                          
4107          text.clear();                                                                                             
4108          // Populate event with a fake title based on the current state.                                           
4109          if (mState == State.APPS_CUSTOMIZE) {                                                                     
4110              text.add(mAppsCustomizeTabHost.getContentTag());                                                      
4111          } else {                                                                                                  
4112              text.add(getString(R.string.all_apps_home_button_label));                                             
4113          }                                                                                                         
4114          return result;                                                                                            
4115      }                                                                                                             
4116                                                                                                                    
4117      /**                                                                                                           
4118       * Receives notifications when system dialogs are to be closed.                                               
4119       */                                                                                                           
4120      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4121          @Override                                                                                                 
4122          public void onReceive(Context context, Intent intent) {                                                   
4123              closeSystemDialogs();                                                                                 
4124          }                                                                                                         
4125      }                                                                                                             
4126                                                                                                                    
4127      /**                                                                                                           
4128       * Receives notifications whenever the appwidgets are reset.                                                  
4129       */                                                                                                           
4130      private class AppWidgetResetObserver extends ContentObserver {                                                
4131          public AppWidgetResetObserver() {                                                                         
4132              super(new Handler());                                                                                 
4133          }                                                                                                         
4134                                                                                                                    
4135          @Override                                                                                                 
4136          public void onChange(boolean selfChange) {                                                                
4137              onAppWidgetReset();                                                                                   
4138          }                                                                                                         
4139      }                                                                                                             
4140                                                                                                                    
4141      /**                                                                                                           
4142       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4143       * in onResume.                                                                                               
4144       *                                                                                                            
4145       * This needs to be called from incoming places where resources might have been loaded                        
4146       * while we are paused.  That is becaues the Configuration might be wrong                                     
4147       * when we're not running, and if it comes back to what it was when we                                        
4148       * were paused, we are not restarted.                                                                         
4149       *                                                                                                            
4150       * Implementation of the method from LauncherModel.Callbacks.                                                 
4151       *                                                                                                            
4152       * @return true if we are currently paused.  The caller might be able to                                      
4153       * skip some work in that case since we will come back again.                                                 
4154       */                                                                                                           
4155      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4156          if (mPaused) {                                                                                            
4157              Log.i(TAG, "Deferring update until onResume");                                                        
4158              if (deletePreviousRunnables) {                                                                        
4159                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4160                  }                                                                                                 
4161              }                                                                                                     
4162              mBindOnResumeCallbacks.add(run);                                                                      
4163              return true;                                                                                          
4164          } else {                                                                                                  
4165              return false;                                                                                         
4166          }                                                                                                         
4167      }                                                                                                             
4168                                                                                                                    
4169      private boolean waitUntilResume(Runnable run) {                                                               
4170          return waitUntilResume(run, false);                                                                       
4171      }                                                                                                             
4172                                                                                                                    
4173      public void addOnResumeCallback(Runnable run) {                                                               
4174          mOnResumeCallbacks.add(run);                                                                              
4175      }                                                                                                             
4176                                                                                                                    
4177      /**                                                                                                           
4178       * If the activity is currently paused, signal that we need to re-run the loader                              
4179       * in onResume.                                                                                               
4180       *                                                                                                            
4181       * This needs to be called from incoming places where resources might have been loaded                        
4182       * while we are paused.  That is becaues the Configuration might be wrong                                     
4183       * when we're not running, and if it comes back to what it was when we                                        
4184       * were paused, we are not restarted.                                                                         
4185       *                                                                                                            
4186       * Implementation of the method from LauncherModel.Callbacks.                                                 
4187       *                                                                                                            
4188       * @return true if we are currently paused.  The caller might be able to                                      
4189       * skip some work in that case since we will come back again.                                                 
4190       */                                                                                                           
4191      public boolean setLoadOnResume() {                                                                            
4192          if (mPaused) {                                                                                            
4193              Log.i(TAG, "setLoadOnResume");                                                                        
4194              mOnResumeNeedsLoad = true;                                                                            
4195              return true;                                                                                          
4196          } else {                                                                                                  
4197              return false;                                                                                         
4198          }                                                                                                         
4199      }                                                                                                             
4200                                                                                                                    
4201      /**                                                                                                           
4202       * Implementation of the method from LauncherModel.Callbacks.                                                 
4203       */                                                                                                           
4204      public int getCurrentWorkspaceScreen() {                                                                      
4205          if (mWorkspace != null) {                                                                                 
4206              return mWorkspace.getCurrentPage();                                                                   
4207          } else {                                                                                                  
4208              return SCREEN_COUNT / 2;                                                                              
4209          }                                                                                                         
4210      }                                                                                                             
4211                                                                                                                    
4212      /**                                                                                                           
4213       * Refreshes the shortcuts shown on the workspace.                                                            
4214       *                                                                                                            
4215       * Implementation of the method from LauncherModel.Callbacks.                                                 
4216       */                                                                                                           
4217      public void startBinding() {                                                                                  
4218          setWorkspaceLoading(true);                                                                                
4219                                                                                                                    
4220          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4221          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4222          // from scratch again                                                                                     
4223          mBindOnResumeCallbacks.clear();                                                                           
4224                                                                                                                    
4225          // Clear the workspace because it's going to be rebound                                                   
4226          mWorkspace.clearDropTargets();                                                                            
4227          mWorkspace.removeAllWorkspaceScreens();                                                                   
4228                                                                                                                    
4229          mWidgetsToAdvance.clear();                                                                                
4230          if (mHotseat != null) {                                                                                   
4231              mHotseat.resetLayout();                                                                               
4232          }                                                                                                         
4233      }                                                                                                             
4234                                                                                                                    
4235      @Override                                                                                                     
4236      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4237          bindAddScreens(orderedScreenIds);                                                                         
4238                                                                                                                    
4239          // If there are no screens, we need to have an empty screen                                               
4240          if (orderedScreenIds.size() == 0) {                                                                       
4241              mWorkspace.addExtraEmptyScreen();                                                                     
4242          }                                                                                                         
4243                                                                                                                    
4244          // Create the custom content page (this call updates mDefaultScreen which calls                           
4245          // setCurrentPage() so ensure that all pages are added before calling this).                              
4246          if (hasCustomContentToLeft()) {                                                                           
4247              mWorkspace.createCustomContentContainer();                                                            
4248              populateCustomContentContainer();                                                                     
4249          }                                                                                                         
4250      }                                                                                                             
4251                                                                                                                    
4252      @Override                                                                                                     
4253      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4254          // Log to disk                                                                                            
4255          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4256          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4257                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4258          int count = orderedScreenIds.size();                                                                      
4259          for (int i = 0; i < count; i++) {                                                                         
4260              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4261          }                                                                                                         
4262      }                                                                                                             
4263                                                                                                                    
4264      private boolean shouldShowWeightWatcher() {                                                                   
4265          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4266          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4267          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4268                                                                                                                    
4269          return show;                                                                                              
4270      }                                                                                                             
4271                                                                                                                    
4272      private void toggleShowWeightWatcher() {                                                                      
4273          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4274          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4275          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4276                                                                                                                    
4277          show = !show;                                                                                             
4278                                                                                                                    
4279          SharedPreferences.Editor editor = sp.edit();                                                              
4280          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4281          editor.commit();                                                                                          
4282                                                                                                                    
4283          if (mWeightWatcher != null) {                                                                             
4284              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4285          }                                                                                                         
4286      }                                                                                                             
4287                                                                                                                    
4288      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4289                                final ArrayList<ItemInfo> addNotAnimated,                                           
4290                                final ArrayList<ItemInfo> addAnimated,                                              
4291                                final ArrayList<AppInfo> addedApps) {                                               
4292          Runnable r = new Runnable() {                                                                             
4293              public void run() {                                                                                   
4294                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4295              }                                                                                                     
4296          };                                                                                                        
4297          if (waitUntilResume(r)) {                                                                                 
4298              return;                                                                                               
4299          }                                                                                                         
4300                                                                                                                    
4301          // Add the new screens                                                                                    
4302          if (newScreens != null) {                                                                                 
4303              bindAddScreens(newScreens);                                                                           
4304          }                                                                                                         
4305                                                                                                                    
4306          // We add the items without animation on non-visible pages, and with                                      
4307          // animations on the new page (which we will try and snap to).                                            
4308          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4309              bindItems(addNotAnimated, 0,                                                                          
4310                      addNotAnimated.size(), false);                                                                
4311          }                                                                                                         
4312          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4313              bindItems(addAnimated, 0,                                                                             
4314                      addAnimated.size(), true);                                                                    
4315          }                                                                                                         
4316                                                                                                                    
4317          // Remove the extra empty screen                                                                          
4318          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4319                                                                                                                    
4320          if (!LauncherAppState.isDisableAllApps() &&                                                               
4321                  addedApps != null && mAppsCustomizeContent != null) {                                             
4322              mAppsCustomizeContent.addApps(addedApps);                                                             
4323          }                                                                                                         
4324      }                                                                                                             
4325                                                                                                                    
4326      /**                                                                                                           
4327       * Bind the items start-end from the list.                                                                    
4328       *                                                                                                            
4329       * Implementation of the method from LauncherModel.Callbacks.                                                 
4330       */                                                                                                           
4331      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4332                            final boolean forceAnimateIcons) {                                                      
4333          Runnable r = new Runnable() {                                                                             
4334              public void run() {                                                                                   
4335                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4336              }                                                                                                     
4337          };                                                                                                        
4338          if (waitUntilResume(r)) {                                                                                 
4339              return;                                                                                               
4340          }                                                                                                         
4341                                                                                                                    
4342          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4343          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4344          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4345          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4346          Workspace workspace = mWorkspace;                                                                         
4347          long newShortcutsScreenId = -1;                                                                           
4348          for (int i = start; i < end; i++) {                                                                       
4349              final ItemInfo item = shortcuts.get(i);                                                               
4350                                                                                                                    
4351              // Short circuit if we are loading dock items for a configuration which has no dock                   
4352              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4353                      mHotseat == null) {                                                                           
4354                  continue;                                                                                         
4355              }                                                                                                     
4356                                                                                                                    
4357              switch (item.itemType) {                                                                              
4358                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4359                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4360                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4361                      View shortcut = createShortcut(info);                                                         
4362                                                                                                                    
4363                      /*                                                                                            
4364                       * TODO: FIX collision case                                                                   
4365                       */                                                                                           
4366                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4367                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4368                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4369                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4370                              Object tag = v.getTag();                                                              
4371                              String desc = "Collision while binding workspace item: " + item                       
4372                                      + ". Collides with " + tag;                                                   
4373                              if (LauncherAppState.isDogfoodBuild()) {                                              
4374                                  throw (new RuntimeException(desc));                                               
4375                              } else {                                                                              
4376                                  Log.d(TAG, desc);                                                                 
4377                              }                                                                                     
4378                          }                                                                                         
4379                      }                                                                                             
4380                                                                                                                    
4381                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4382                              item.cellY, 1, 1);                                                                    
4383                      if (animateIcons) {                                                                           
4384                          // Animate all the applications up now                                                    
4385                          shortcut.setAlpha(0f);                                                                    
4386                          shortcut.setScaleX(0f);                                                                   
4387                          shortcut.setScaleY(0f);                                                                   
4388                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4389                          newShortcutsScreenId = item.screenId;                                                     
4390                      }                                                                                             
4391                      break;                                                                                        
4392                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4393                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4394                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4395                              (FolderInfo) item, mIconCache);                                                       
4396                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4397                              item.cellY, 1, 1);                                                                    
4398                      break;                                                                                        
4399                  default:                                                                                          
4400                      throw new RuntimeException("Invalid Item Type");                                              
4401              }                                                                                                     
4402          }                                                                                                         
4403                                                                                                                    
4404          if (animateIcons) {                                                                                       
4405              // Animate to the correct page                                                                        
4406              if (newShortcutsScreenId > -1) {                                                                      
4407                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4408                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4409                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4410                      public void run() {                                                                           
4411                          anim.playTogether(bounceAnims);                                                           
4412                          anim.start();                                                                             
4413                      }                                                                                             
4414                  };                                                                                                
4415                  if (newShortcutsScreenId != currentScreenId) {                                                    
4416                      // We post the animation slightly delayed to prevent slowdowns                                
4417                      // when we are loading right after we return to launcher.                                     
4418                      mWorkspace.postDelayed(new Runnable() {                                                       
4419                          public void run() {                                                                       
4420                              if (mWorkspace != null) {                                                             
4421                                  mWorkspace.snapToPage(newScreenIndex);                                            
4422                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4423                                          NEW_APPS_ANIMATION_DELAY);                                                
4424                              }                                                                                     
4425                          }                                                                                         
4426                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4427                  } else {                                                                                          
4428                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4429                  }                                                                                                 
4430              }                                                                                                     
4431          }                                                                                                         
4432          workspace.requestLayout();                                                                                
4433      }                                                                                                             
4434                                                                                                                    
4435      /**                                                                                                           
4436       * Implementation of the method from LauncherModel.Callbacks.                                                 
4437       */                                                                                                           
4438      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4439          Runnable r = new Runnable() {                                                                             
4440              public void run() {                                                                                   
4441                  bindFolders(folders);                                                                             
4442              }                                                                                                     
4443          };                                                                                                        
4444          if (waitUntilResume(r)) {                                                                                 
4445              return;                                                                                               
4446          }                                                                                                         
4447          sFolders.clear();                                                                                         
4448          sFolders.putAll(folders);                                                                                 
4449      }                                                                                                             
4450                                                                                                                    
4451      /**                                                                                                           
4452       * Add the views for a widget to the workspace.                                                               
4453       *                                                                                                            
4454       * Implementation of the method from LauncherModel.Callbacks.                                                 
4455       */                                                                                                           
4456      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4457          Runnable r = new Runnable() {                                                                             
4458              public void run() {                                                                                   
4459                  bindAppWidget(item);                                                                              
4460              }                                                                                                     
4461          };                                                                                                        
4462          if (waitUntilResume(r)) {                                                                                 
4463              return;                                                                                               
4464          }                                                                                                         
4465                                                                                                                    
4466          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4467          if (DEBUG_WIDGETS) {                                                                                      
4468              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4469          }                                                                                                         
4470          final Workspace workspace = mWorkspace;                                                                   
4471                                                                                                                    
4472          AppWidgetProviderInfo appWidgetInfo;                                                                      
4473          if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&                        
4474                  ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                          
4475                                                                                                                    
4476              appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);               
4477              if (appWidgetInfo == null) {                                                                          
4478                  if (DEBUG_WIDGETS) {                                                                              
4479                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4480                              + " belongs to component " + item.providerName                                        
4481                              + ", as the povider is null");                                                        
4482                  }                                                                                                 
4483                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4484                  return;                                                                                           
4485              }                                                                                                     
4486              // Note: This assumes that the id remap broadcast is received before this step.                       
4487              // If that is not the case, the id remap will be ignored and user may see the                         
4488              // click to setup view.                                                                               
4489              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);               
4490              pendingInfo.spanX = item.spanX;                                                                       
4491              pendingInfo.spanY = item.spanY;                                                                       
4492              pendingInfo.minSpanX = item.minSpanX;                                                                 
4493              pendingInfo.minSpanY = item.minSpanY;                                                                 
4494              Bundle options =                                                                                      
4495                      AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
4496                                                                                                                    
4497              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4498              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4499                      newWidgetId, appWidgetInfo, options);                                                         
4500                                                                                                                    
4501              // TODO consider showing a permission dialog when the widget is clicked.                              
4502              if (!success) {                                                                                       
4503                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4504                  if (DEBUG_WIDGETS) {                                                                              
4505                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4506                              + " belongs to component " + item.providerName                                        
4507                              + ", as the launcher is unable to bing a new widget id");                             
4508                  }                                                                                                 
4509                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4510                  return;                                                                                           
4511              }                                                                                                     
4512                                                                                                                    
4513              item.appWidgetId = newWidgetId;                                                                       
4514                                                                                                                    
4515              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4516              // the widget is ready to go.                                                                         
4517              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4518                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4519                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4520                                                                                                                    
4521              LauncherModel.updateItemInDatabase(this, item);                                                       
4522          }                                                                                                         
4523                                                                                                                    
4524          if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                                      
4525              final int appWidgetId = item.appWidgetId;                                                             
4526              appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                                      
4527              if (DEBUG_WIDGETS) {                                                                                  
4528                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidgetInfo.prov🔵
4529              }                                                                                                     
4530                                                                                                                    
4531              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4532          } else {                                                                                                  
4533              appWidgetInfo = null;                                                                                 
4534              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                             
4535              view.updateIcon(mIconCache);                                                                          
4536              item.hostView = view;                                                                                 
4537              item.hostView.updateAppWidget(null);                                                                  
4538              item.hostView.setOnClickListener(this);                                                               
4539          }                                                                                                         
4540                                                                                                                    
4541          item.hostView.setTag(item);                                                                               
4542          item.onBindAppWidget(this);                                                                               
4543                                                                                                                    
4544          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4545                  item.cellY, item.spanX, item.spanY, false);                                                       
4546          addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                             
4547                                                                                                                    
4548          workspace.requestLayout();                                                                                
4549                                                                                                                    
4550          if (DEBUG_WIDGETS) {                                                                                      
4551              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4552                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4553          }                                                                                                         
4554      }                                                                                                             
4555                                                                                                                    
4556      /**                                                                                                           
4557       * Restores a pending widget.                                                                                 
4558       *                                                                                                            
4559       * @param appWidgetId The app widget id                                                                       
4560       * @param cellInfo The position on screen where to create the widget.                                         
4561       */                                                                                                           
4562      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4563          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4564          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4565              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4566              return;                                                                                               
4567          }                                                                                                         
4568                                                                                                                    
4569          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4570          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4571                                                                                                                    
4572          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4573          LauncherModel.updateItemInDatabase(this, info);                                                           
4574      }                                                                                                             
4575                                                                                                                    
4576      public void onPageBoundSynchronously(int page) {                                                              
4577          mSynchronouslyBoundPages.add(page);                                                                       
4578      }                                                                                                             
4579                                                                                                                    
4580      /**                                                                                                           
4581       * Callback saying that there aren't any more items to bind.                                                  
4582       *                                                                                                            
4583       * Implementation of the method from LauncherModel.Callbacks.                                                 
4584       */                                                                                                           
4585      public void finishBindingItems(final boolean upgradePath) {                                                   
4586          Runnable r = new Runnable() {                                                                             
4587              public void run() {                                                                                   
4588                  finishBindingItems(upgradePath);                                                                  
4589              }                                                                                                     
4590          };                                                                                                        
4591          if (waitUntilResume(r)) {                                                                                 
4592              return;                                                                                               
4593          }                                                                                                         
4594          if (mSavedState != null) {                                                                                
4595              if (!mWorkspace.hasFocus()) {                                                                         
4596                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4597              }                                                                                                     
4598              mSavedState = null;                                                                                   
4599          }                                                                                                         
4600                                                                                                                    
4601          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4602                                                                                                                    
4603          setWorkspaceLoading(false);                                                                               
4604          sendLoadingCompleteBroadcastIfNecessary();                                                                
4605                                                                                                                    
4606          // If we received the result of any pending adds while the loader was running (e.g. the                   
4607          // widget configuration forced an orientation change), process them now.                                  
4608          if (sPendingAddItem != null) {                                                                            
4609              final long screenId = completeAdd(sPendingAddItem);                                                   
4610                                                                                                                    
4611              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4612              // the screen would be guaranteed to exist after bind, and the page would be set through              
4613              // the workspace restore process.                                                                     
4614              mWorkspace.post(new Runnable() {                                                                      
4615                  @Override                                                                                         
4616                  public void run() {                                                                               
4617                      mWorkspace.snapToScreenId(screenId);                                                          
4618                  }                                                                                                 
4619              });                                                                                                   
4620              sPendingAddItem = null;                                                                               
4621          }                                                                                                         
4622                                                                                                                    
4623          if (upgradePath) {                                                                                        
4624              mWorkspace.getUniqueComponents(true, null);                                                           
4625              mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4626          }                                                                                                         
4627          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  

4628      }                                                                                                             
4629                                                                                                                    
4630      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4631          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4632              String permission =                                                                                   
4633                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4634              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4635              sendBroadcast(intent, permission);                                                                    
4636              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4637              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4638              editor.apply();                                                                                       
4639          }                                                                                                         
4640      }                                                                                                             
4641                                                                                                                    
4642      public boolean isAllAppsButtonRank(int rank) {                                                                
4643          if (mHotseat != null) {                                                                                   
4644              return mHotseat.isAllAppsButtonRank(rank);                                                            
4645          }                                                                                                         
4646          return false;                                                                                             
4647      }                                                                                                             
4648                                                                                                                    
4649      private boolean canRunNewAppsAnimation() {                                                                    
4650          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4651          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4652      }                                                                                                             
4653                                                                                                                    
4654      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4655          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4656                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4657                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4658                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4659          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4660          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4661          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4662          return bounceAnim;                                                                                        
4663      }                                                                                                             
4664                                                                                                                    
4665      public boolean useVerticalBarLayout() {                                                                       
4666          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4667                  getDeviceProfile().isVerticalBarLayout();                                                         
4668      }                                                                                                             
4669                                                                                                                    
4670      protected Rect getSearchBarBounds() {                                                                         
4671          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4672                  getDeviceProfile().getSearchBarBounds();                                                          
4673      }                                                                                                             
4674                                                                                                                    
4675      @Override                                                                                                     
4676      public void bindSearchablesChanged() {                                                                        
4677          boolean searchVisible = updateGlobalSearchIcon();                                                         
4678          boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                              
4679          if (mSearchDropTargetBar != null) {                                                                       
4680              mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                            
4681          }                                                                                                         
4682      }                                                                                                             
4683                                                                                                                    
4684      /**                                                                                                           
4685       * Add the icons for all apps.                                                                                
4686       *                                                                                                            
4687       * Implementation of the method from LauncherModel.Callbacks.                                                 
4688       */                                                                                                           
4689      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4690          if (LauncherAppState.isDisableAllApps()) {                                                                
4691              if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4692                  if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4693                      getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4694                              mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4695                  }                                                                                                 
4696                  mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4697              }                                                                                                     
4698              if (mAppsCustomizeContent != null) {                                                                  
4699                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4700                          LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
4701              }                                                                                                     
4702          } else {                                                                                                  
4703              if (mAppsCustomizeContent != null) {                                                                  
4704                  mAppsCustomizeContent.setApps(apps);                                                              
4705                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4706                          LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
4707              }                                                                                                     
4708          }                                                                                                         
4709      }                                                                                                             
4710                                                                                                                    
4711      /**                                                                                                           
4712       * A package was updated.                                                                                     
4713       *                                                                                                            
4714       * Implementation of the method from LauncherModel.Callbacks.                                                 
4715       */                                                                                                           
4716      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
4717          Runnable r = new Runnable() {                                                                             
4718              public void run() {                                                                                   
4719                  bindAppsUpdated(apps);                                                                            
4720              }                                                                                                     
4721          };                                                                                                        
4722          if (waitUntilResume(r)) {                                                                                 
4723              return;                                                                                               
4724          }                                                                                                         
4725                                                                                                                    
4726          if (mWorkspace != null) {                                                                                 
4727              mWorkspace.updateShortcutsAndWidgets(apps);                                                           
4728          }                                                                                                         
4729                                                                                                                    
4730          if (!LauncherAppState.isDisableAllApps() &&                                                               
4731                  mAppsCustomizeContent != null) {                                                                  
4732              mAppsCustomizeContent.updateApps(apps);                                                               


















4733          }                                                                                                         
4734      }                                                                                                             
4735                                                                                                                    
4736      /**                                                                                                           
4737 +     * Some shortcuts were updated in the background.                                                             
4738 +     *                                                                                                            
4739 +     * Implementation of the method from LauncherModel.Callbacks.                                                 
4740 +     */                                                                                                           
4741 +    public void bindShortcutsUpdated(final ArrayList<ShortcutInfo> shortcuts) {                                   
4742 +        Runnable r = new Runnable() {                                                                             
4743 +            public void run() {                                                                                   
4744 +                bindShortcutsUpdated(shortcuts);                                                                  
4745 +            }                                                                                                     
4746 +        };                                                                                                        
4747 +        if (waitUntilResume(r)) {                                                                                 
4748 +            return;                                                                                               
4749 +        }                                                                                                         
4750 +                                                                                                                  
4751 +        if (mWorkspace != null) {                                                                                 
4752 +            mWorkspace.updateShortcuts(shortcuts);                                                                
4753 +        }                                                                                                         
4754 +    }                                                                                                             
4755 +                                                                                                                  
4756 +    /**                                                                                                           
4757       * Update the state of a package, typically related to install state.                                         
4758       *                                                                                                            
4759       * Implementation of the method from LauncherModel.Callbacks.                                                 
4760       */                                                                                                           
4761      @Override                                                                                                     
4762      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
4763          if (mWorkspace != null) {                                                                                 
4764              mWorkspace.updatePackageState(installInfo);                                                           
4765          }                                                                                                         
4766      }                                                                                                             
4767                                                                                                                    
4768      /**                                                                                                           
4769       * Update the label and icon of all the icons in a package                                                    
4770       *                                                                                                            
4771       * Implementation of the method from LauncherModel.Callbacks.                                                 
4772       */                                                                                                           
4773      @Override                                                                                                     
4774      public void updatePackageBadge(String packageName) {                                                          
4775          if (mWorkspace != null) {                                                                                 
4776              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
4777          }                                                                                                         
4778      }                                                                                                             
4779                                                                                                                    
4780      /**                                                                                                           
4781       * A package was uninstalled.  We take both the super set of packageNames                                     
4782       * in addition to specific applications to remove, the reason being that                                      
4783       * this can be called when a package is updated as well.  In that scenario,                                   
4784       * we only remove specific components from the workspace, where as                                            
4785       * package-removal should clear all items by package name.                                                    
4786       *                                                                                                            
4787 +     * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
4788       * Implementation of the method from LauncherModel.Callbacks.                                                 
4789       */                                                                                                           
4790 +    @Override                                                                                                     
4791      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
4792 -            final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {                                     
4793 +            final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
4794          Runnable r = new Runnable() {                                                                             
4795              public void run() {                                                                                   
4796 -                bindComponentsRemoved(packageNames, appInfos, user);                                              
4797 +                bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
4798              }                                                                                                     
4799          };                                                                                                        
4800          if (waitUntilResume(r)) {                                                                                 
4801              return;                                                                                               
4802          }                                                                                                         
4803                                                                                                                    
4804 -        if (!packageNames.isEmpty()) {                                                                            
4805 -            mWorkspace.removeItemsByPackageName(packageNames, user);                                              
4806 -        }                                                                                                         
4807 -        if (!appInfos.isEmpty()) {                                                                                
4808 -            mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                              
4809 +        if (reason == 0) {                                                                                        
4810 +            if (!packageNames.isEmpty()) {                                                                        
4811 +                mWorkspace.removeItemsByPackageName(packageNames, user);                                          
4812 +            }                                                                                                     
4813 +            if (!appInfos.isEmpty()) {                                                                            
4814 +                mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                          
4815 +            }                                                                                                     
4816 +        } else {                                                                                                  
4817 +            mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
4818          }                                                                                                         
4819                                                                                                                    
4820          // Notify the drag controller                                                                             
4821          mDragController.onAppsRemoved(packageNames, appInfos);                                                    
4822                                                                                                                    
4823          // Update AllApps                                                                                         
4824          if (!LauncherAppState.isDisableAllApps() &&                                                               
4825                  mAppsCustomizeContent != null) {                                                                  
4826              mAppsCustomizeContent.removeApps(appInfos);                                                           
4827          }                                                                                                         
4828      }                                                                                                             
4829                                                                                                                    
4830      /**                                                                                                           
4831       * A number of packages were updated.                                                                         
4832       */                                                                                                           
4833      private ArrayList<Object> mWidgetsAndShortcuts;                                                               
4834      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
4835              public void run() {                                                                                   
4836                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
4837                  mWidgetsAndShortcuts = null;                                                                      
4838              }                                                                                                     
4839          };                                                                                                        
4840      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
4841          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
4842              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
4843              return;                                                                                               
4844          }                                                                                                         
4845                                                                                                                    
4846          // Update the widgets pane                                                                                
4847          if (mAppsCustomizeContent != null) {                                                                      
4848              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
4849          }                                                                                                         
4850      }                                                                                                             
4851                                                                                                                    
4852      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
4853          final Display d = getWindowManager().getDefaultDisplay();                                                 
4854          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
4855          switch (d.getRotation()) {                                                                                
4856          case Surface.ROTATION_0:                                                                                  
4857          case Surface.ROTATION_180:                                                                                
4858              // We are currently in the same basic orientation as the natural orientation                          
4859              naturalOri = configOri;                                                                               
4860              break;                                                                                                
4861          case Surface.ROTATION_90:                                                                                 
4862          case Surface.ROTATION_270:                                                                                
4863              // We are currently in the other basic orientation to the natural orientation                         
4864              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
4865                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
4866              break;                                                                                                
4867          }                                                                                                         
4868                                                                                                                    
4869          int[] oriMap = {                                                                                          
4870                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
4871                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
4872                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
4873                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
4874          };                                                                                                        
4875          // Since the map starts at portrait, we need to offset if this device's natural orientation               
4876          // is landscape.                                                                                          
4877          int indexOffset = 0;                                                                                      
4878          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
4879              indexOffset = 1;                                                                                      
4880          }                                                                                                         
4881          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
4882      }                                                                                                             
4883                                                                                                                    
4884      public boolean isRotationEnabled() {                                                                          
4885          boolean enableRotation = sForceEnableRotation ||                                                          
4886                  getResources().getBoolean(R.bool.allow_rotation);                                                 
4887          return enableRotation;                                                                                    
4888      }                                                                                                             
4889      public void lockScreenOrientation() {                                                                         
4890          if (isRotationEnabled()) {                                                                                
4891              setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                             
4892                      .getConfiguration().orientation));                                                            
4893          }                                                                                                         
4894      }                                                                                                             
4895      public void unlockScreenOrientation(boolean immediate) {                                                      
4896          if (isRotationEnabled()) {                                                                                
4897              if (immediate) {                                                                                      
4898                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
4899              } else {                                                                                              
4900                  mHandler.postDelayed(new Runnable() {                                                             
4901                      public void run() {                                                                           
4902                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
4903                      }                                                                                             
4904                  }, mRestoreScreenOrientationDelay);                                                               
4905              }                                                                                                     
4906          }                                                                                                         
4907      }                                                                                                             
4908                                                                                                                    
4909      /**                                                                                                           
4910       * Called when the SearchBar hint should be changed.                                                          
4911       *                                                                                                            
4912       * @param hint the hint to be displayed in the search bar.                                                    
4913       */                                                                                                           
4914      protected void onSearchBarHintChanged(String hint) {                                                          
4915                                                                                                                    
4916      }                                                                                                             
4917                                                                                                                    
4918      protected boolean isLauncherPreinstalled() {                                                                  
4919          PackageManager pm = getPackageManager();                                                                  
4920          try {                                                                                                     
4921              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
4922              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
4923                  return true;                                                                                      
4924              } else {                                                                                              
4925                  return false;                                                                                     
4926              }                                                                                                     
4927          } catch (NameNotFoundException e) {                                                                       
4928              e.printStackTrace();                                                                                  
4929              return false;                                                                                         
4930          }                                                                                                         
4931      }                                                                                                             
4932                                                                                                                    
4933      /**                                                                                                           
4934       * This method indicates whether or not we should suggest default wallpaper dimensions                        
4935       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
4936       */                                                                                                           
4937      protected boolean overrideWallpaperDimensions() {                                                             
4938          return true;                                                                                              
4939 -    }                                                                                                             
4940 -                                                                                                                  
4941 -    protected boolean shouldClingFocusHotseatApp() {                                                              
4942 -        return false;                                                                                             
4943 -    }                                                                                                             
4944 -    protected String getFirstRunClingSearchBarHint() {                                                            
4945 -        return "";                                                                                                
4946 -    }                                                                                                             
4947 -    protected String getFirstRunCustomContentHint() {                                                             
4948 -        return "";                                                                                                
4949 -    }                                                                                                             
4950 -    protected int getFirstRunFocusedHotseatAppDrawableId() {                                                      
4951 -        return -1;                                                                                                
4952 -    }                                                                                                             
4953 -    protected ComponentName getFirstRunFocusedHotseatAppComponentName() {                                         
4954 -        return null;                                                                                              
4955 -    }                                                                                                             
4956 -    protected int getFirstRunFocusedHotseatAppRank() {                                                            
4957 -        return -1;                                                                                                
4958 -    }                                                                                                             
4959 -    protected String getFirstRunFocusedHotseatAppBubbleTitle() {                                                  
4960 -        return "";                                                                                                
4961 -    }                                                                                                             
4962 -    protected String getFirstRunFocusedHotseatAppBubbleDescription() {                                            
4963 -        return "";                                                                                                
4964      }                                                                                                             
4965                                                                                                                    
4966      /**                                                                                                           
4967       * To be overridden by subclasses to indicate that there is an activity to launch                             
4968       * before showing the standard launcher experience.                                                           
4969       */                                                                                                           
4970      protected boolean hasFirstRunActivity() {                                                                     
4971          return false;                                                                                             
4972      }                                                                                                             
4973                                                                                                                    
4974      /**                                                                                                           
4975       * To be overridden by subclasses to launch any first run activity                                            
4976       */                                                                                                           
4977      protected Intent getFirstRunActivity() {                                                                      
4978          return null;                                                                                              
4979      }                                                                                                             
4980                                                                                                                    
4981      private boolean shouldRunFirstRunActivity() {                                                                 
4982          return !ActivityManager.isRunningInTestHarness() &&                                                       
4983                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
4984      }                                                                                                             
4985                                                                                                                    
4986      protected boolean hasRunFirstRunActivity() {                                                                  
4987          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
4988      }                                                                                                             
4989                                                                                                                    
4990      public boolean showFirstRunActivity() {                                                                       
4991          if (shouldRunFirstRunActivity() &&                                                                        
4992                  hasFirstRunActivity()) {                                                                          
4993              Intent firstRunIntent = getFirstRunActivity();                                                        
4994              if (firstRunIntent != null) {                                                                         
4995                  startActivity(firstRunIntent);                                                                    
4996                  markFirstRunActivityShown();                                                                      
4997                  return true;                                                                                      
4998              }                                                                                                     
4999          }                                                                                                         
5000          return false;                                                                                             
5001      }                                                                                                             
5002                                                                                                                    
5003      private void markFirstRunActivityShown() {                                                                    
5004          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5005          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
5006          editor.apply();                                                                                           
5007      }                                                                                                             
5008                                                                                                                    
5009      /**                                                                                                           
5010       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
5011       * screen that must be displayed and dismissed.                                                               
5012       */                                                                                                           
5013      protected boolean hasDismissableIntroScreen() {                                                               
5014          return false;                                                                                             
5015      }                                                                                                             
5016                                                                                                                    
5017      /**                                                                                                           
5018       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
5019       */                                                                                                           
5020      protected View getIntroScreen() {                                                                             
5021          return null;                                                                                              
5022      }                                                                                                             
5023                                                                                                                    
5024      /**                                                                                                           
5025       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
5026       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
5027       */                                                                                                           
5028      private boolean shouldShowIntroScreen() {                                                                     
5029          return hasDismissableIntroScreen() &&                                                                     
5030                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
5031      }                                                                                                             
5032                                                                                                                    
5033      protected void showIntroScreen() {                                                                            
5034          View introScreen = getIntroScreen();                                                                      
5035          changeWallpaperVisiblity(false);                                                                          
5036          if (introScreen != null) {                                                                                
5037              mDragLayer.showOverlayView(introScreen);                                                              
5038          }                                                                                                         
5039      }                                                                                                             
5040                                                                                                                    
5041      public void dismissIntroScreen() {                                                                            
5042          markIntroScreenDismissed();                                                                               
5043          if (showFirstRunActivity()) {                                                                             
5044              // We delay hiding the intro view until the first run activity is showing. This                       
5045              // avoids a blip.                                                                                     
5046              mWorkspace.postDelayed(new Runnable() {                                                               
5047                  @Override                                                                                         
5048                  public void run() {                                                                               
5049                      mDragLayer.dismissOverlayView();                                                              
5050                      showFirstRunClings();                                                                         
5051                  }                                                                                                 
5052              }, ACTIVITY_START_DELAY);                                                                             
5053          } else {                                                                                                  
5054              mDragLayer.dismissOverlayView();                                                                      
5055              showFirstRunClings();                                                                                 
5056          }                                                                                                         
5057          changeWallpaperVisiblity(true);                                                                           
5058      }                                                                                                             
5059                                                                                                                    
5060      private void markIntroScreenDismissed() {                                                                     
5061          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5062          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5063          editor.apply();                                                                                           
5064      }                                                                                                             
5065                                                                                                                    
5066      private void showFirstRunClings() {                                                                           
5067          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5068          // on the device, then we always show the first run cling experience (or if there is no                   
5069          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5070          LauncherClings launcherClings = new LauncherClings(this);                                                 
5071          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5072              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5073                  launcherClings.showMigrationCling();                                                              
5074              } else {                                                                                              
5075                  launcherClings.showLongPressCling(true);                                                          
5076              }                                                                                                     
5077          }                                                                                                         
5078      }                                                                                                             
5079                                                                                                                    
5080      void showWorkspaceSearchAndHotseat() {                                                                        
5081          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5082          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5083          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5084          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5085      }                                                                                                             
5086                                                                                                                    
5087      void hideWorkspaceSearchAndHotseat() {                                                                        
5088          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5089          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5090          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5091          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5092      }                                                                                                             
5093                                                                                                                    
5094      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5095          // Called from search suggestion, not supported in other profiles.                                        
5096          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5097          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5098          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5099                  myUser);                                                                                          
5100          if (activityInfo == null) {                                                                               
5101              return null;                                                                                          
5102          }                                                                                                         
5103          return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         
5104      }                                                                                                             
5105                                                                                                                    
5106      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5107              Bitmap icon) {                                                                                        
5108          // Called from search suggestion, not supported in other profiles.                                        
5109          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5110                  UserHandleCompat.myUserHandle());                                                                 
5111      }                                                                                                             
5112                                                                                                                    
5113      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5114              Bitmap icon, UserHandleCompat user) {                                                                 
5115          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5116          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5117          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5118      }                                                                                                             
5119                                                                                                                    
5120      protected void moveWorkspaceToDefaultScreen() {                                                               
5121          mWorkspace.moveToDefaultScreen(false);                                                                    
5122      }                                                                                                             
5123                                                                                                                    
5124      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5125          dragView.setTag(dragInfo);                                                                                
5126          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5127          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5128      }                                                                                                             
5129                                                                                                                    
5130      @Override                                                                                                     
5131      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5132      }                                                                                                             
5133                                                                                                                    
5134      /**                                                                                                           
5135       * Prints out out state for debugging.                                                                        
5136       */                                                                                                           
5137      public void dumpState() {                                                                                     
5138          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5139          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5140          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5141          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5142          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5143          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5144          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5145          mModel.dumpState();                                                                                       
5146                                                                                                                    
5147          if (mAppsCustomizeContent != null) {                                                                      
5148              mAppsCustomizeContent.dumpState();                                                                    
5149          }                                                                                                         
5150          Log.d(TAG, "END launcher3 dump state");                                                                   
5151      }                                                                                                             
5152                                                                                                                    
5153      @Override                                                                                                     
5154      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5155          super.dump(prefix, fd, writer, args);                                                                     
5156          synchronized (sDumpLogs) {                                                                                
5157              writer.println(" ");                                                                                  
5158              writer.println("Debug logs: ");                                                                       
5159              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5160                  writer.println("  " + sDumpLogs.get(i));                                                          
5161              }                                                                                                     
5162          }                                                                                                         
5163      }                                                                                                             
5164                                                                                                                    
5165      public static void dumpDebugLogsToConsole() {                                                                 
5166          if (DEBUG_DUMP_LOG) {                                                                                     
5167              synchronized (sDumpLogs) {                                                                            
5168                  Log.d(TAG, "");                                                                                   
5169                  Log.d(TAG, "*********************");                                                              
5170                  Log.d(TAG, "Launcher debug logs: ");                                                              
5171                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5172                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5173                  }                                                                                                 
5174                  Log.d(TAG, "*********************");                                                              
5175                  Log.d(TAG, "");                                                                                   
5176              }                                                                                                     
5177          }                                                                                                         
5178      }                                                                                                             
5179                                                                                                                    
5180      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5181          addDumpLog(tag, log, null, debugLog);                                                                     
5182      }                                                                                                             
5183                                                                                                                    
5184      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5185          if (debugLog) {                                                                                           
5186              if (e != null) {                                                                                      
5187                  Log.d(tag, log, e);                                                                               
5188              } else {                                                                                              
5189                  Log.d(tag, log);                                                                                  
5190              }                                                                                                     
5191          }                                                                                                         
5192          if (DEBUG_DUMP_LOG) {                                                                                     
5193              sDateStamp.setTime(System.currentTimeMillis());                                                       
5194              synchronized (sDumpLogs) {                                                                            
5195                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5196                      + (e == null ? "" : (", Exception: " + e)));                                                  
5197              }                                                                                                     
5198          }                                                                                                         
5199      }                                                                                                             
5200                                                                                                                    
5201      public void dumpLogsToLocalData() {                                                                           
5202          if (DEBUG_DUMP_LOG) {                                                                                     
5203              new AsyncTask<Void, Void, Void>() {                                                                   
5204                  public Void doInBackground(Void ... args) {                                                       
5205                      boolean success = false;                                                                      
5206                      sDateStamp.setTime(sRunStart);                                                                
5207                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5208                              + sDateStamp.getDay() + "_"                                                           
5209                              + sDateStamp.getHours() + "-"                                                         
5210                              + sDateStamp.getMinutes() + "_"                                                       
5211                              + sDateStamp.getSeconds() + ".txt";                                                   
5212                                                                                                                    
5213                      FileOutputStream fos = null;                                                                  
5214                      File outFile = null;                                                                          
5215                      try {                                                                                         
5216                          outFile = new File(getFilesDir(), FILENAME);                                              
5217                          outFile.createNewFile();                                                                  
5218                          fos = new FileOutputStream(outFile);                                                      
5219                      } catch (Exception e) {                                                                       
5220                          e.printStackTrace();                                                                      
5221                      }                                                                                             
5222                      if (fos != null) {                                                                            
5223                          PrintWriter writer = new PrintWriter(fos);                                                
5224                                                                                                                    
5225                          writer.println(" ");                                                                      
5226                          writer.println("Debug logs: ");                                                           
5227                          synchronized (sDumpLogs) {                                                                
5228                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5229                                  writer.println("  " + sDumpLogs.get(i));                                          
5230                              }                                                                                     
5231                          }                                                                                         
5232                          writer.close();                                                                           
5233                      }                                                                                             
5234                      try {                                                                                         
5235                          if (fos != null) {                                                                        
5236                              fos.close();                                                                          
5237                              success = true;                                                                       
5238                          }                                                                                         
5239                      } catch (IOException e) {                                                                     
5240                          e.printStackTrace();                                                                      
5241                      }                                                                                             
5242                      return null;                                                                                  
5243                  }                                                                                                 
5244              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5245          }                                                                                                         
5246      }                                                                                                             
5247  }                                                                                                                 
5248                                                                                                                    
5249  interface LauncherTransitionable {                                                                                
5250      View getContent();                                                                                            
5251      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5252      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5253      void onLauncherTransitionStep(Launcher l, float t);                                                           
5254      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5255  }                                                                                                                 
5256                                                                                                                    
5257  interface DebugIntents {                                                                                          
5258      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5259      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5260  }                                                                                                                 
   1                                                                                                                    
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25  import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.SharedPreferences;                                                                         
  46  import android.content.pm.ActivityInfo;                                                                           
  47  import android.content.pm.ApplicationInfo;                                                                        
  48  import android.content.pm.PackageManager;                                                                         
  49  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  50  import android.content.res.Configuration;                                                                         
  51  import android.content.res.Resources;                                                                             
  52  import android.database.ContentObserver;                                                                          
  53  import android.graphics.Bitmap;                                                                                   
  54  import android.graphics.Canvas;                                                                                   
  55  import android.graphics.Color;                                                                                    
  56  import android.graphics.Point;                                                                                    
  57  import android.graphics.PorterDuff;                                                                               
  58  import android.graphics.Rect;                                                                                     
  59  import android.graphics.drawable.Drawable;                                                                        
  60  import android.net.Uri;                                                                                           
  61  import android.os.AsyncTask;                                                                                      
  62  import android.os.Build;                                                                                          
  63  import android.os.Bundle;                                                                                         
  64  import android.os.Environment;                                                                                    
  65  import android.os.Handler;                                                                                        
  66  import android.os.Message;                                                                                        
  67  import android.os.StrictMode;                                                                                     
  68  import android.os.SystemClock;                                                                                    
  69  import android.speech.RecognizerIntent;                                                                           
  70  import android.text.Selection;                                                                                    
  71  import android.text.SpannableStringBuilder;                                                                       
  72  import android.text.TextUtils;                                                                                    
  73  import android.text.method.TextKeyListener;                                                                       
  74  import android.util.DisplayMetrics;                                                                               
  75  import android.util.Log;                                                                                          
  76  import android.view.ContextThemeWrapper;                                                                          
  77  import android.view.Display;                                                                                      
  78  import android.view.Gravity;                                                                                      
  79  import android.view.HapticFeedbackConstants;                                                                      
  80  import android.view.KeyEvent;                                                                                     
  81  import android.view.LayoutInflater;                                                                               
  82  import android.view.Menu;                                                                                         
  83  import android.view.MotionEvent;                                                                                  
  84  import android.view.Surface;                                                                                      
  85  import android.view.View;                                                                                         
  86  import android.view.View.OnClickListener;                                                                         
  87  import android.view.View.OnLongClickListener;                                                                     
  88  import android.view.ViewAnimationUtils;                                                                           
  89  import android.view.ViewGroup;                                                                                    
  90  import android.view.ViewTreeObserver;                                                                             
  91  import android.view.ViewTreeObserver.OnGlobalLayoutListener;                                                      
  92  import android.view.Window;                                                                                       
  93  import android.view.WindowManager;                                                                                
  94  import android.view.accessibility.AccessibilityEvent;                                                             
  95  import android.view.animation.AccelerateInterpolator;                                                             
  96  import android.view.animation.DecelerateInterpolator;                                                             
  97  import android.view.animation.Interpolator;                                                                       
  98  import android.view.inputmethod.InputMethodManager;                                                               
  99  import android.widget.Advanceable;                                                                                
 100  import android.widget.FrameLayout;                                                                                
 101  import android.widget.ImageView;                                                                                  
 102  import android.widget.TextView;                                                                                   
 103  import android.widget.Toast;                                                                                      
 104                                                                                                                    
 105  import com.android.launcher3.DropTarget.DragObject;                                                               
 106  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 107  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 108  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 109  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 110  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 111  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 112  import com.android.launcher3.compat.UserHandleCompat;                                                             
 113  import com.android.launcher3.compat.UserManagerCompat;                                                            
 114                                                                                                                    
 115  import java.io.DataInputStream;                                                                                   
 116  import java.io.DataOutputStream;                                                                                  
 117  import java.io.File;                                                                                              
 118  import java.io.FileDescriptor;                                                                                    
 119  import java.io.FileNotFoundException;                                                                             
 120  import java.io.FileOutputStream;                                                                                  
 121  import java.io.IOException;                                                                                       
 122  import java.io.PrintWriter;                                                                                       
 123  import java.lang.reflect.Field;                                                                                   
 124  import java.lang.reflect.InvocationTargetException;                                                               
 125  import java.lang.reflect.Method;                                                                                  
 126  import java.text.DateFormat;                                                                                      
 127  import java.util.ArrayList;                                                                                       
 128  import java.util.Collection;                                                                                      
 129  import java.util.Date;                                                                                            
 130  import java.util.HashMap;                                                                                         
 131  import java.util.List;                                                                                            
 132  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 133                                                                                                                    
 134  /**                                                                                                               
 135   * Default launcher application.                                                                                  
 136   */                                                                                                               
 137  public class Launcher extends Activity                                                                            
 138          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 139                     View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     
 140      static final String TAG = "Launcher";                                                                         
 141      static final boolean LOGD = false;                                                                            
 142                                                                                                                    
 143      static final boolean PROFILE_STARTUP = false;                                                                 
 144      static final boolean DEBUG_WIDGETS = false;                                                                   
 145      static final boolean DEBUG_STRICT_MODE = false;                                                               
 146      static final boolean DEBUG_RESUME_TIME = false;                                                               
 147      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 148                                                                                                                    
 149      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 150                                                                                                                    
 151      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 152      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 153      private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 154      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 155      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 156                                                                                                                    
 157      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 158      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 159                                                                                                                    
 160      /**                                                                                                           
 161       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 162       * request codes used internally.                                                                             
 163       */                                                                                                           
 164      protected static final int REQUEST_LAST = 100;                                                                
 165                                                                                                                    
 166      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 167                                                                                                                    
 168      static final int SCREEN_COUNT = 5;                                                                            
 169      static final int DEFAULT_SCREEN = 2;                                                                          
 170                                                                                                                    
 171      private static final String PREFERENCES = "launcher.preferences";                                             
 172      // To turn on these properties, type                                                                          
 173      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 174      static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                                 
 175      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 176      static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 177                                                                                                                    
 178      // The Intent extra that defines whether to ignore the launch animation                                       
 179      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 180              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 181                                                                                                                    
 182      // Type: int                                                                                                  
 183      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 184      // Type: int                                                                                                  
 185      private static final String RUNTIME_STATE = "launcher.state";                                                 
 186      // Type: int                                                                                                  
 187      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 188      // Type: int                                                                                                  
 189      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 190      // Type: int                                                                                                  
 191      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 192      // Type: int                                                                                                  
 193      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 194      // Type: boolean                                                                                              
 195      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 196      // Type: long                                                                                                 
 197      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 198      // Type: int                                                                                                  
 199      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 200      // Type: int                                                                                                  
 201      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 202      // Type: parcelable                                                                                           
 203      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 204      // Type: parcelable                                                                                           
 205      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 206      // Type: int[]                                                                                                
 207      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 208                                                                                                                    
 209      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 210      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 211                                                                                                                    
 212      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 213      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 214              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 215                                                                                                                    
 216      private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";                 
 217      private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                               
 218              "com.android.launcher.toolbar_search_icon";                                                           
 219      private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                         
 220              "com.android.launcher.toolbar_voice_search_icon";                                                     
 221                                                                                                                    
 222      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 223      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 224                                                                                                                    
 225      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 226                                                                                                                    
 227      /** The different states that Launcher can be in. */                                                          
 228      private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 229      private State mState = State.WORKSPACE;                                                                       
 230      private AnimatorSet mStateAnimation;                                                                          
 231                                                                                                                    
 232      private boolean mIsSafeModeEnabled;                                                                           
 233                                                                                                                    
 234      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 235      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 236      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 237      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 238                                                                                                                    
 239      private static final Object sLock = new Object();                                                             
 240      private static int sScreen = DEFAULT_SCREEN;                                                                  
 241                                                                                                                    
 242      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 243      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 244                                                                                                                    
 245      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 246      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 247      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 248      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 249      private static final int SINGLE_FRAME_DELAY = 16;                                                             
 250                                                                                                                    
 251      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 252              = new CloseSystemDialogsIntentReceiver();                                                             
 253      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 254                                                                                                                    
 255      private LayoutInflater mInflater;                                                                             
 256                                                                                                                    
 257      private Workspace mWorkspace;                                                                                 
 258      private View mLauncherView;                                                                                   
 259      private View mPageIndicators;                                                                                 
 260      private DragLayer mDragLayer;                                                                                 
 261      private DragController mDragController;                                                                       
 262      private View mWeightWatcher;                                                                                  
 263                                                                                                                    
 264      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 265      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 266                                                                                                                    
 267      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 268      private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                          
 269      private int mPendingAddWidgetId = -1;                                                                         
 270                                                                                                                    
 271      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 272                                                                                                                    
 273      private FolderInfo mFolderInfo;                                                                               
 274                                                                                                                    
 275      private Hotseat mHotseat;                                                                                     
 276      private ViewGroup mOverviewPanel;                                                                             
 277                                                                                                                    
 278      private View mAllAppsButton;                                                                                  
 279                                                                                                                    
 280      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 281      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 282      private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 283      private boolean mAutoAdvanceRunning = false;                                                                  
 284      private View mQsb;                                                                                            
 285                                                                                                                    
 286      private Bundle mSavedState;                                                                                   
 287      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 288      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 289      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 290      private State mOnResumeState = State.NONE;                                                                    
 291                                                                                                                    
 292      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 293                                                                                                                    
 294      private boolean mWorkspaceLoading = true;                                                                     
 295                                                                                                                    
 296      private boolean mPaused = true;                                                                               
 297      private boolean mRestoring;                                                                                   
 298      private boolean mWaitingForResult;                                                                            
 299      private boolean mOnResumeNeedsLoad;                                                                           
 300                                                                                                                    
 301      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 302      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 303                                                                                                                    
 304      private Bundle mSavedInstanceState;                                                                           
 305                                                                                                                    
 306      private LauncherModel mModel;                                                                                 
 307      private IconCache mIconCache;                                                                                 
 308      private boolean mUserPresent = true;                                                                          
 309      private boolean mVisible = false;                                                                             
 310      private boolean mHasFocus = false;                                                                            
 311      private boolean mAttached = false;                                                                            
 312                                                                                                                    
 313      private static LocaleConfiguration sLocaleConfiguration = null;                                               
 314                                                                                                                    
 315      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 316                                                                                                                    
 317      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 318                                                                                                                    
 319      // Related to the auto-advancing of widgets                                                                   
 320      private final int ADVANCE_MSG = 1;                                                                            
 321      private final int mAdvanceInterval = 20000;                                                                   
 322      private final int mAdvanceStagger = 250;                                                                      
 323      private long mAutoAdvanceSentTime;                                                                            
 324      private long mAutoAdvanceTimeLeft = -1;                                                                       
 325      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 326          new HashMap<View, AppWidgetProviderInfo>();                                                               
 327                                                                                                                    
 328      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 329      // match the sensor state.                                                                                    
 330      private final int mRestoreScreenOrientationDelay = 500;                                                       
 331                                                                                                                    
 332      // External icons saved in case of resource changes, orientation, etc.                                        
 333      private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];                    
 334      private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];                     
 335                                                                                                                    
 336      private Drawable mWorkspaceBackgroundDrawable;                                                                
 337                                                                                                                    
 338      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 339      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 340                                                                                                                    
 341      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 342      static Date sDateStamp = new Date();                                                                          
 343      static DateFormat sDateFormat =                                                                               
 344              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 345      static long sRunStart = System.currentTimeMillis();                                                           
 346      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 347                                                                                                                    
 348      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 349      // it from the context.                                                                                       
 350      private SharedPreferences mSharedPrefs;                                                                       
 351                                                                                                                    
 352      private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 353                                                                                                                    
 354      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 355      // when we scroll to that page on resume.                                                                     
 356      private ImageView mFolderIconImageView;                                                                       
 357      private Bitmap mFolderIconBitmap;                                                                             
 358      private Canvas mFolderIconCanvas;                                                                             
 359      private Rect mRectForFolderAnimation = new Rect();                                                            
 360                                                                                                                    
 361      private BubbleTextView mWaitingForResume;                                                                     
 362                                                                                                                    
 363      private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 364          public void run() {                                                                                       
 365              if (mWorkspace != null) {                                                                             
 366                  mWorkspace.buildPageHardwareLayers();                                                             
 367              }                                                                                                     
 368          }                                                                                                         
 369      };                                                                                                            
 370                                                                                                                    
 371      private static PendingAddArguments sPendingAddItem;                                                           
 372                                                                                                                    
 373      public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);               
 374                                                                                                                    
 375      private static class PendingAddArguments {                                                                    
 376          int requestCode;                                                                                          
 377          Intent intent;                                                                                            
 378          long container;                                                                                           
 379          long screenId;                                                                                            
 380          int cellX;                                                                                                
 381          int cellY;                                                                                                
 382          int appWidgetId;                                                                                          
 383      }                                                                                                             
 384                                                                                                                    
 385      private Stats mStats;                                                                                         
 386                                                                                                                    
 387      FocusIndicatorView mFocusHandler;                                                                             
 388                                                                                                                    
 389      static boolean isPropertyEnabled(String propertyName) {                                                       
 390          return Log.isLoggable(propertyName, Log.VERBOSE);                                                         
 391      }                                                                                                             
 392                                                                                                                    
 393      @Override                                                                                                     
 394      protected void onCreate(Bundle savedInstanceState) {                                                          
 395          if (DEBUG_STRICT_MODE) {                                                                                  
 396              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 397                      .detectDiskReads()                                                                            
 398                      .detectDiskWrites()                                                                           
 399                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 400                      .penaltyLog()                                                                                 
 401                      .build());                                                                                    
 402              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 403                      .detectLeakedSqlLiteObjects()                                                                 
 404                      .detectLeakedClosableObjects()                                                                
 405                      .penaltyLog()                                                                                 
 406                      .penaltyDeath()                                                                               
 407                      .build());                                                                                    
 408          }                                                                                                         
 409                                                                                                                    
 410          super.onCreate(savedInstanceState);                                                                       
 411                                                                                                                    
 412          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 413          LauncherAppState app = LauncherAppState.getInstance();                                                    
 414          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 415          // Determine the dynamic grid properties                                                                  
 416          Point smallestSize = new Point();                                                                         
 417          Point largestSize = new Point();                                                                          
 418          Point realSize = new Point();                                                                             
 419          Display display = getWindowManager().getDefaultDisplay();                                                 
 420          display.getCurrentSizeRange(smallestSize, largestSize);                                                   
 421          display.getRealSize(realSize);                                                                            
 422          DisplayMetrics dm = new DisplayMetrics();                                                                 
 423          display.getMetrics(dm);                                                                                   
 424                                                                                                                    
 425          // Lazy-initialize the dynamic grid                                                                       
 426          DeviceProfile grid = app.initDynamicGrid(this,                                                            
 427                  Math.min(smallestSize.x, smallestSize.y),                                                         
 428                  Math.min(largestSize.x, largestSize.y),                                                           
 429                  realSize.x, realSize.y,                                                                           
 430                  dm.widthPixels, dm.heightPixels);                                                                 
 431                                                                                                                    
 432          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 433          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 434                  Context.MODE_PRIVATE);                                                                            
 435          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 436          mModel = app.setLauncher(this);                                                                           
 437          mIconCache = app.getIconCache();                                                                          
 438          mIconCache.flushInvalidIcons(grid);                                                                       
 439          mDragController = new DragController(this);                                                               
 440          mInflater = getLayoutInflater();                                                                          
 441                                                                                                                    
 442          mStats = new Stats(this);                                                                                 
 443                                                                                                                    
 444          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 445                                                                                                                    
 446          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 447          mAppWidgetHost.startListening();                                                                          
 448                                                                                                                    
 449          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 450          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 451          // LauncherModel load.                                                                                    
 452          mPaused = false;                                                                                          
 453                                                                                                                    
 454          if (PROFILE_STARTUP) {                                                                                    
 455              android.os.Debug.startMethodTracing(                                                                  
 456                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 457          }                                                                                                         
 458                                                                                                                    
 459          checkForLocaleChange();                                                                                   
 460          setContentView(R.layout.launcher);                                                                        
 461                                                                                                                    
 462          setupViews();                                                                                             
 463          grid.layout(this);                                                                                        
 464                                                                                                                    
 465          registerContentObservers();                                                                               
 466                                                                                                                    
 467          lockAllApps();                                                                                            
 468                                                                                                                    
 469          mSavedState = savedInstanceState;                                                                         
 470          restoreState(mSavedState);                                                                                
 471                                                                                                                    
 472          if (PROFILE_STARTUP) {                                                                                    
 473              android.os.Debug.stopMethodTracing();                                                                 
 474          }                                                                                                         
 475                                                                                                                    
 476          if (!mRestoring) {                                                                                        
 477              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 478                  // If the user leaves launcher, then we should just load items asynchronously when                
 479                  // they return.                                                                                   
 480                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 481              } else {                                                                                              
 482                  // We only load the page synchronously if the user rotates (or triggers a                         
 483                  // configuration change) while launcher is in the foreground                                      
 484                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 485              }                                                                                                     
 486          }                                                                                                         
 487                                                                                                                    
 488          // For handling default keys                                                                              
 489          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 490          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 491                                                                                                                    
 492          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 493          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 494                                                                                                                    
 495          updateGlobalIcons();                                                                                      
 496                                                                                                                    
 497          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 498          unlockScreenOrientation(true);                                                                            
 499                                                                                                                    
 500          if (shouldShowIntroScreen()) {                                                                            
 501              showIntroScreen();                                                                                    
 502          } else {                                                                                                  
 503              showFirstRunActivity();                                                                               
 504              showFirstRunClings();                                                                                 
 505          }                                                                                                         
 506      }                                                                                                             
 507                                                                                                                    
 508      @Override                                                                                                     
 509      public void onLauncherProviderChange() { }                                                                    
 510                                                                                                                    
 511      /** To be overriden by subclasses to hint to Launcher that we have custom content */                          
 512      protected boolean hasCustomContentToLeft() {                                                                  
 513          return false;                                                                                             
 514      }                                                                                                             
 515                                                                                                                    
 516      /**                                                                                                           
 517       * To be overridden by subclasses to populate the custom content container and call                           
 518       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 519       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 520       */                                                                                                           
 521      protected void populateCustomContentContainer() {                                                             
 522      }                                                                                                             
 523                                                                                                                    
 524      /**                                                                                                           
 525       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 526       * ensure the custom content page is added or removed if necessary.                                           
 527       */                                                                                                           
 528      protected void invalidateHasCustomContentToLeft() {                                                           
 529          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 530              // Not bound yet, wait for bindScreens to be called.                                                  
 531              return;                                                                                               
 532          }                                                                                                         
 533                                                                                                                    
 534          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 535              // Create the custom content page and call the subclass to populate it.                               
 536              mWorkspace.createCustomContentContainer();                                                            
 537              populateCustomContentContainer();                                                                     
 538          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 539              mWorkspace.removeCustomContentPage();                                                                 
 540          }                                                                                                         
 541      }                                                                                                             
 542                                                                                                                    
 543      private void updateGlobalIcons() {                                                                            
 544          boolean searchVisible = false;                                                                            
 545          boolean voiceVisible = false;                                                                             
 546          // If we have a saved version of these external icons, we load them up immediately                        
 547          int coi = getCurrentOrientationIndexForGlobalIcons();                                                     
 548          if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                                    
 549              searchVisible = updateGlobalSearchIcon();                                                             
 550              voiceVisible = updateVoiceSearchIcon(searchVisible);                                                  
 551          }                                                                                                         
 552          if (sGlobalSearchIcon[coi] != null) {                                                                     
 553               updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                                      
 554               searchVisible = true;                                                                                
 555          }                                                                                                         
 556          if (sVoiceSearchIcon[coi] != null) {                                                                      
 557              updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                         
 558              voiceVisible = true;                                                                                  
 559          }                                                                                                         
 560          if (mSearchDropTargetBar != null) {                                                                       
 561              mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                            
 562          }                                                                                                         
 563      }                                                                                                             
 564                                                                                                                    
 565      private void checkForLocaleChange() {                                                                         
 566          if (sLocaleConfiguration == null) {                                                                       
 567              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 568                  @Override                                                                                         
 569                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 570                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 571                      readConfiguration(Launcher.this, localeConfiguration);                                        
 572                      return localeConfiguration;                                                                   
 573                  }                                                                                                 
 574                                                                                                                    
 575                  @Override                                                                                         
 576                  protected void onPostExecute(LocaleConfiguration result) {                                        
 577                      sLocaleConfiguration = result;                                                                
 578                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 579                  }                                                                                                 
 580              }.execute();                                                                                          
 581              return;                                                                                               
 582          }                                                                                                         
 583                                                                                                                    
 584          final Configuration configuration = getResources().getConfiguration();                                    
 585                                                                                                                    
 586          final String previousLocale = sLocaleConfiguration.locale;                                                
 587          final String locale = configuration.locale.toString();                                                    
 588                                                                                                                    
 589          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 590          final int mcc = configuration.mcc;                                                                        
 591                                                                                                                    
 592          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 593          final int mnc = configuration.mnc;                                                                        
 594                                                                                                                    
 595          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 596                                                                                                                    
 597          if (localeChanged) {                                                                                      
 598              sLocaleConfiguration.locale = locale;                                                                 
 599              sLocaleConfiguration.mcc = mcc;                                                                       
 600              sLocaleConfiguration.mnc = mnc;                                                                       
 601                                                                                                                    
 602              mIconCache.flush();                                                                                   
 603                                                                                                                    
 604              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 605              new AsyncTask<Void, Void, Void>() {                                                                   
 606                  public Void doInBackground(Void ... args) {                                                       
 607                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 608                      return null;                                                                                  
 609                  }                                                                                                 
 610              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 611          }                                                                                                         
 612      }                                                                                                             
 613                                                                                                                    
 614      private static class LocaleConfiguration {                                                                    
 615          public String locale;                                                                                     
 616          public int mcc = -1;                                                                                      
 617          public int mnc = -1;                                                                                      
 618      }                                                                                                             
 619                                                                                                                    
 620      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 621          DataInputStream in = null;                                                                                
 622          try {                                                                                                     
 623              in = new DataInputStream(context.openFileInput(PREFERENCES));                                         

 624              configuration.locale = in.readUTF();                                                                  
 625              configuration.mcc = in.readInt();                                                                     
 626              configuration.mnc = in.readInt();                                                                     
 627          } catch (FileNotFoundException e) {                                                                       
 628              // Ignore                                                                                             
 629          } catch (IOException e) {                                                                                 
 630              // Ignore                                                                                             
 631          } finally {                                                                                               
 632              if (in != null) {                                                                                     
 633                  try {                                                                                             
 634                      in.close();                                                                                   
 635                  } catch (IOException e) {                                                                         
 636                      // Ignore                                                                                     
 637                  }                                                                                                 
 638              }                                                                                                     
 639          }                                                                                                         
 640      }                                                                                                             
 641                                                                                                                    
 642      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 643          DataOutputStream out = null;                                                                              
 644          try {                                                                                                     
 645              out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));                        


 646              out.writeUTF(configuration.locale);                                                                   
 647              out.writeInt(configuration.mcc);                                                                      
 648              out.writeInt(configuration.mnc);                                                                      
 649              out.flush();                                                                                          
 650          } catch (FileNotFoundException e) {                                                                       
 651              // Ignore                                                                                             
 652          } catch (IOException e) {                                                                                 
 653              //noinspection ResultOfMethodCallIgnored                                                              
 654              context.getFileStreamPath(PREFERENCES).delete();                                                      

 655          } finally {                                                                                               
 656              if (out != null) {                                                                                    
 657                  try {                                                                                             
 658                      out.close();                                                                                  
 659                  } catch (IOException e) {                                                                         
 660                      // Ignore                                                                                     
 661                  }                                                                                                 
 662              }                                                                                                     
 663          }                                                                                                         
 664      }                                                                                                             
 665                                                                                                                    
 666      public Stats getStats() {                                                                                     
 667          return mStats;                                                                                            
 668      }                                                                                                             
 669                                                                                                                    
 670      public LayoutInflater getInflater() {                                                                         
 671          return mInflater;                                                                                         
 672      }                                                                                                             
 673                                                                                                                    
 674      boolean isDraggingEnabled() {                                                                                 
 675          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 676          // that is subsequently removed from the workspace in startBinding().                                     
 677          return !mModel.isLoadingWorkspace();                                                                      
 678      }                                                                                                             
 679                                                                                                                    
 680      static int getScreen() {                                                                                      
 681          synchronized (sLock) {                                                                                    
 682              return sScreen;                                                                                       
 683          }                                                                                                         
 684      }                                                                                                             
 685                                                                                                                    
 686      static void setScreen(int screen) {                                                                           
 687          synchronized (sLock) {                                                                                    
 688              sScreen = screen;                                                                                     
 689          }                                                                                                         
 690      }                                                                                                             
 691                                                                                                                    
 692      public static int generateViewId() {                                                                          
 693          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 694              return View.generateViewId();                                                                         
 695          } else {                                                                                                  
 696              // View.generateViewId() is not available. The following fallback logic is a copy                     
 697              // of its implementation.                                                                             
 698              for (;;) {                                                                                            
 699                  final int result = sNextGeneratedId.get();                                                        
 700                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 701                  int newValue = result + 1;                                                                        
 702                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 703                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 704                      return result;                                                                                
 705                  }                                                                                                 
 706              }                                                                                                     
 707          }                                                                                                         
 708      }                                                                                                             
 709                                                                                                                    
 710      public int getViewIdForItem(ItemInfo info) {                                                                  
 711          // This cast is safe given the > 2B range for int.                                                        
 712          int itemId = (int) info.id;                                                                               
 713          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 714              return mItemIdToViewId.get(itemId);                                                                   
 715          }                                                                                                         
 716          int viewId = generateViewId();                                                                            
 717          mItemIdToViewId.put(itemId, viewId);                                                                      
 718          return viewId;                                                                                            
 719      }                                                                                                             
 720                                                                                                                    
 721      /**                                                                                                           
 722       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 723       * a configuration step, this allows the proper animations to run after other transitions.                    
 724       */                                                                                                           
 725      private long completeAdd(PendingAddArguments args) {                                                          
 726          long screenId = args.screenId;                                                                            
 727          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 728              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 729              // that the drop page actually exists.                                                                
 730              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 731          }                                                                                                         
 732                                                                                                                    
 733          switch (args.requestCode) {                                                                               
 734              case REQUEST_CREATE_SHORTCUT:                                                                         
 735                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 736                          args.cellY);                                                                              
 737                  break;                                                                                            
 738              case REQUEST_CREATE_APPWIDGET:                                                                        
 739                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 740                  break;                                                                                            
 741              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 742                  completeRestoreAppWidget(args.appWidgetId);                                                       
 743                  break;                                                                                            
 744          }                                                                                                         
 745          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 746          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 747          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 748          resetAddInfo();                                                                                           
 749          return screenId;                                                                                          
 750      }                                                                                                             
 751                                                                                                                    
 752      @Override                                                                                                     
 753      protected void onActivityResult(                                                                              
 754              final int requestCode, final int resultCode, final Intent data) {                                     
 755          // Reset the startActivity waiting flag                                                                   
 756          setWaitingForResult(false);                                                                               
 757          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 758          mPendingAddWidgetId = -1;                                                                                 
 759                                                                                                                    
 760          Runnable exitSpringLoaded = new Runnable() {                                                              
 761              @Override                                                                                             
 762              public void run() {                                                                                   
 763                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 764                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 765              }                                                                                                     
 766          };                                                                                                        
 767                                                                                                                    
 768          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 769              final int appWidgetId = data != null ?                                                                
 770                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 771              if (resultCode == RESULT_CANCELED) {                                                                  
 772                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 773                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 774                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 775              } else if (resultCode == RESULT_OK) {                                                                 
 776                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 777                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 778              }                                                                                                     
 779              return;                                                                                               
 780          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 781              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 782                  mWorkspace.exitOverviewMode(false);                                                               
 783              }                                                                                                     
 784              return;                                                                                               
 785          }                                                                                                         
 786                                                                                                                    
 787          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 788                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 789                                                                                                                    
 790          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 791          // We have special handling for widgets                                                                   
 792          if (isWidgetDrop) {                                                                                       
 793              final int appWidgetId;                                                                                
 794              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 795                      : -1;                                                                                         
 796              if (widgetId < 0) {                                                                                   
 797                  appWidgetId = pendingAddWidgetId;                                                                 
 798              } else {                                                                                              
 799                  appWidgetId = widgetId;                                                                           
 800              }                                                                                                     
 801                                                                                                                    
 802              final int result;                                                                                     
 803              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 804                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 805                          "returned from the widget configuration activity.");                                      
 806                  result = RESULT_CANCELED;                                                                         
 807                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 808                  final Runnable onComplete = new Runnable() {                                                      
 809                      @Override                                                                                     
 810                      public void run() {                                                                           
 811                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 812                      }                                                                                             
 813                  };                                                                                                
 814                  if (workspaceLocked) {                                                                            
 815                      // No need to remove the empty screen if we're mid-binding, as the                            
 816                      // the bind will not add the empty screen.                                                    
 817                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 818                  } else {                                                                                          
 819                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 820                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 821                  }                                                                                                 
 822              } else {                                                                                              
 823                  if (!workspaceLocked) {                                                                           
 824                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 825                          // When the screen id represents an actual screen (as opposed to a rank)                  
 826                          // we make sure that the drop page actually exists.                                       
 827                          mPendingAddInfo.screenId =                                                                
 828                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 829                      }                                                                                             
 830                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 831                                                                                                                    
 832                      dropLayout.setDropPending(true);                                                              
 833                      final Runnable onComplete = new Runnable() {                                                  
 834                          @Override                                                                                 
 835                          public void run() {                                                                       
 836                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 837                              dropLayout.setDropPending(false);                                                     
 838                          }                                                                                         
 839                      };                                                                                            
 840                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 841                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 842                  } else {                                                                                          
 843                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 844                              mPendingAddInfo);                                                                     
 845                      sPendingAddItem = args;                                                                       
 846                  }                                                                                                 
 847              }                                                                                                     
 848              return;                                                                                               
 849          }                                                                                                         
 850                                                                                                                    
 851          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 852              if (resultCode == RESULT_OK) {                                                                        
 853                  // Update the widget view.                                                                        
 854                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 855                          pendingAddWidgetId, mPendingAddInfo);                                                     
 856                  if (workspaceLocked) {                                                                            
 857                      sPendingAddItem = args;                                                                       
 858                  } else {                                                                                          
 859                      completeAdd(args);                                                                            
 860                  }                                                                                                 
 861              }                                                                                                     
 862              // Leave the widget in the pending state if the user canceled the configure.                          
 863              return;                                                                                               
 864          }                                                                                                         
 865                                                                                                                    
 866          // The pattern used here is that a user PICKs a specific application,                                     
 867          // which, depending on the target, might need to CREATE the actual target.                                
 868                                                                                                                    
 869          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 870          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 871          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 872              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 873                      mPendingAddInfo);                                                                             
 874              if (isWorkspaceLocked()) {                                                                            
 875                  sPendingAddItem = args;                                                                           
 876              } else {                                                                                              
 877                  completeAdd(args);                                                                                
 878                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 879                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 880              }                                                                                                     
 881          } else if (resultCode == RESULT_CANCELED) {                                                               
 882              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 883                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 884          }                                                                                                         
 885          mDragLayer.clearAnimatedView();                                                                           
 886      }                                                                                                             
 887                                                                                                                    
 888      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 889              appWidgetId, ItemInfo info) {                                                                         
 890          PendingAddArguments args = new PendingAddArguments();                                                     
 891          args.requestCode = requestCode;                                                                           
 892          args.intent = data;                                                                                       
 893          args.container = info.container;                                                                          
 894          args.screenId = info.screenId;                                                                            
 895          args.cellX = info.cellX;                                                                                  
 896          args.cellY = info.cellY;                                                                                  
 897          args.appWidgetId = appWidgetId;                                                                           
 898          return args;                                                                                              
 899      }                                                                                                             
 900                                                                                                                    
 901      /**                                                                                                           
 902       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 903       *                                                                                                            
 904       * @param screenId the screen id to check                                                                     
 905       * @return the new screen, or screenId if it exists                                                           
 906       */                                                                                                           
 907      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 908          CellLayout dropLayout =                                                                                   
 909                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 910          if (dropLayout == null) {                                                                                 
 911              // it's possible that the add screen was removed because it was                                       
 912              // empty and a re-bind occurred                                                                       
 913              mWorkspace.addExtraEmptyScreen();                                                                     
 914              return mWorkspace.commitExtraEmptyScreen();                                                           
 915          } else {                                                                                                  
 916              return screenId;                                                                                      
 917          }                                                                                                         
 918      }                                                                                                             
 919                                                                                                                    
 920      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
 921          CellLayout cellLayout =                                                                                   
 922                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 923          Runnable onCompleteRunnable = null;                                                                       
 924          int animationType = 0;                                                                                    
 925                                                                                                                    
 926          AppWidgetHostView boundWidget = null;                                                                     
 927          if (resultCode == RESULT_OK) {                                                                            
 928              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 929              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 930                      mPendingAddWidgetInfo);                                                                       
 931              boundWidget = layout;                                                                                 
 932              onCompleteRunnable = new Runnable() {                                                                 
 933                  @Override                                                                                         
 934                  public void run() {                                                                               
 935                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 936                              mPendingAddInfo.screenId, layout, null);                                              
 937                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 938                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 939                  }                                                                                                 
 940              };                                                                                                    
 941          } else if (resultCode == RESULT_CANCELED) {                                                               
 942              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
 943              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
 944          }                                                                                                         
 945          if (mDragLayer.getAnimatedView() != null) {                                                               
 946              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
 947                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
 948                      animationType, boundWidget, true);                                                            
 949          } else if (onCompleteRunnable != null) {                                                                  
 950              // The animated view may be null in the case of a rotation during widget configuration                
 951              onCompleteRunnable.run();                                                                             
 952          }                                                                                                         
 953      }                                                                                                             
 954                                                                                                                    
 955      @Override                                                                                                     
 956      protected void onStop() {                                                                                     
 957          super.onStop();                                                                                           
 958          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
 959      }                                                                                                             
 960                                                                                                                    
 961      @Override                                                                                                     
 962      protected void onStart() {                                                                                    
 963          super.onStart();                                                                                          
 964          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
 965      }                                                                                                             
 966                                                                                                                    
 967      @Override                                                                                                     
 968      protected void onResume() {                                                                                   
 969          long startTime = 0;                                                                                       
 970          if (DEBUG_RESUME_TIME) {                                                                                  
 971              startTime = System.currentTimeMillis();                                                               
 972              Log.v(TAG, "Launcher.onResume()");                                                                    
 973          }                                                                                                         
 974          super.onResume();                                                                                         
 975                                                                                                                    
 976          // Restore the previous launcher state                                                                    
 977          if (mOnResumeState == State.WORKSPACE) {                                                                  
 978              showWorkspace(false);                                                                                 
 979          } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
 980              showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    
 981          }                                                                                                         
 982          mOnResumeState = State.NONE;                                                                              
 983                                                                                                                    
 984          // Background was set to gradient in onPause(), restore to black if in all apps.                          
 985          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
 986                                                                                                                    
 987          mPaused = false;                                                                                          
 988          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
 989              setWorkspaceLoading(true);                                                                            
 990              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
 991              mRestoring = false;                                                                                   
 992              mOnResumeNeedsLoad = false;                                                                           
 993          }                                                                                                         
 994          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
 995              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
 996              // execute them here                                                                                  
 997              long startTimeCallbacks = 0;                                                                          
 998              if (DEBUG_RESUME_TIME) {                                                                              
 999                  startTimeCallbacks = System.currentTimeMillis();                                                  
1000              }                                                                                                     
1001                                                                                                                    
1002              if (mAppsCustomizeContent != null) {                                                                  
1003                  mAppsCustomizeContent.setBulkBind(true);                                                          
1004              }                                                                                                     
1005              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1006                  mBindOnResumeCallbacks.get(i).run();                                                              
1007              }                                                                                                     
1008              if (mAppsCustomizeContent != null) {                                                                  
1009                  mAppsCustomizeContent.setBulkBind(false);                                                         
1010              }                                                                                                     
1011              mBindOnResumeCallbacks.clear();                                                                       
1012              if (DEBUG_RESUME_TIME) {                                                                              
1013                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1014                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1015              }                                                                                                     
1016          }                                                                                                         
1017          if (mOnResumeCallbacks.size() > 0) {                                                                      
1018              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1019                  mOnResumeCallbacks.get(i).run();                                                                  
1020              }                                                                                                     
1021              mOnResumeCallbacks.clear();                                                                           
1022          }                                                                                                         
1023                                                                                                                    
1024          // Reset the pressed state of icons that were locked in the press state while activities                  
1025          // were launching                                                                                         
1026          if (mWaitingForResume != null) {                                                                          
1027              // Resets the previous workspace icon press state                                                     
1028              mWaitingForResume.setStayPressed(false);                                                              
1029          }                                                                                                         
1030                                                                                                                    
1031          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1032          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1033          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1034          // orientation.                                                                                           
1035          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1036                                                                                                                    
1037          // Process any items that were added while Launcher was away.                                             
1038          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1039                                                                                                                    
1040          // Update the voice search button proxy                                                                   
1041          updateVoiceButtonProxyVisible(false);                                                                     
1042                                                                                                                    
1043          // Again, as with the above scenario, it's possible that one or more of the global icons                  
1044          // were updated in the wrong orientation.                                                                 
1045          updateGlobalIcons();                                                                                      
1046          if (DEBUG_RESUME_TIME) {                                                                                  
1047              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1048          }                                                                                                         
1049                                                                                                                    
1050          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1051              // If we are resuming and the custom content is the current page, we call onShow().                   
1052              // It is also poassible that onShow will instead be called slightly after first layout                
1053              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1054              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1055                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1056              }                                                                                                     
1057          }                                                                                                         
1058          mWorkspace.updateInteractionForState();                                                                   
1059          mWorkspace.onResume();                                                                                    
1060                                                                                                                    
1061          PackageInstallerCompat.getInstance(this).onResume();                                                      
1062      }                                                                                                             
1063                                                                                                                    
1064      @Override                                                                                                     
1065      protected void onPause() {                                                                                    
1066          // Ensure that items added to Launcher are queued until Launcher returns                                  
1067          InstallShortcutReceiver.enableInstallQueue();                                                             
1068          PackageInstallerCompat.getInstance(this).onPause();                                                       
1069                                                                                                                    
1070          super.onPause();                                                                                          
1071          mPaused = true;                                                                                           
1072          mDragController.cancelDrag();                                                                             
1073          mDragController.resetLastGestureUpTime();                                                                 
1074                                                                                                                    
1075          // We call onHide() aggressively. The custom content callbacks should be able to                          
1076          // debounce excess onHide calls.                                                                          
1077          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1078              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1079          }                                                                                                         
1080      }                                                                                                             
1081                                                                                                                    
1082      QSBScroller mQsbScroller = new QSBScroller() {                                                                
1083          int scrollY = 0;                                                                                          
1084                                                                                                                    
1085          @Override                                                                                                 
1086          public void setScrollY(int scroll) {                                                                      
1087              scrollY = scroll;                                                                                     
1088                                                                                                                    
1089              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1090                  mSearchDropTargetBar.setTranslationY(- scrollY);                                                  
1091                  getQsbBar().setTranslationY(-scrollY);                                                            
1092              }                                                                                                     
1093          }                                                                                                         
1094      };                                                                                                            
1095                                                                                                                    
1096      public void resetQSBScroll() {                                                                                
1097          mSearchDropTargetBar.animate().translationY(0).start();                                                   
1098          getQsbBar().animate().translationY(0).start();                                                            
1099      }                                                                                                             
1100                                                                                                                    
1101      public interface CustomContentCallbacks {                                                                     
1102          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1103          // by a onResume or by scrolling otherwise.                                                               
1104          public void onShow(boolean fromResume);                                                                   
1105                                                                                                                    
1106          // Custom content is completely hidden                                                                    
1107          public void onHide();                                                                                     
1108                                                                                                                    
1109          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1110          public void onScrollProgressChanged(float progress);                                                      
1111                                                                                                                    
1112          // Indicates whether the user is allowed to scroll away from the custom content.                          
1113          boolean isScrollingAllowed();                                                                             
1114      }                                                                                                             
1115                                                                                                                    
1116      protected boolean hasSettings() {                                                                             
1117          return false;                                                                                             
1118      }                                                                                                             
1119                                                                                                                    
1120      public interface QSBScroller {                                                                                
1121          public void setScrollY(int scrollY);                                                                      
1122      }                                                                                                             
1123                                                                                                                    
1124      public QSBScroller addToCustomContentPage(View customContent,                                                 
1125              CustomContentCallbacks callbacks, String description) {                                               
1126          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1127          return mQsbScroller;                                                                                      
1128      }                                                                                                             
1129                                                                                                                    
1130      // The custom content needs to offset its content to account for the QSB                                      
1131      public int getTopOffsetForCustomContent() {                                                                   
1132          return mWorkspace.getPaddingTop();                                                                        
1133      }                                                                                                             
1134                                                                                                                    
1135      @Override                                                                                                     
1136      public Object onRetainNonConfigurationInstance() {                                                            
1137          // Flag the loader to stop early before switching                                                         
1138          if (mModel.isCurrentCallbacks(this)) {                                                                    
1139              mModel.stopLoader();                                                                                  
1140          }                                                                                                         
1141          if (mAppsCustomizeContent != null) {                                                                      
1142              mAppsCustomizeContent.surrender();                                                                    
1143          }                                                                                                         
1144          return Boolean.TRUE;                                                                                      
1145      }                                                                                                             
1146                                                                                                                    
1147      // We can't hide the IME if it was forced open.  So don't bother                                              
1148      @Override                                                                                                     
1149      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1150          super.onWindowFocusChanged(hasFocus);                                                                     
1151          mHasFocus = hasFocus;                                                                                     
1152      }                                                                                                             
1153                                                                                                                    
1154      private boolean acceptFilter() {                                                                              
1155          final InputMethodManager inputManager = (InputMethodManager)                                              
1156                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1157          return !inputManager.isFullscreenMode();                                                                  
1158      }                                                                                                             
1159                                                                                                                    
1160      @Override                                                                                                     
1161      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1162          final int uniChar = event.getUnicodeChar();                                                               
1163          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1164          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1165          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1166              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1167                      keyCode, event);                                                                              
1168              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1169                  // something usable has been typed - start a search                                               
1170                  // the typed text will be retrieved and cleared by                                                
1171                  // showSearchDialog()                                                                             
1172                  // If there are multiple keystrokes before the search dialog takes focus,                         
1173                  // onSearchRequested() will be called for every keystroke,                                        
1174                  // but it is idempotent, so it's fine.                                                            
1175                  return onSearchRequested();                                                                       
1176              }                                                                                                     
1177          }                                                                                                         
1178                                                                                                                    
1179          // Eat the long press event so the keyboard doesn't come up.                                              
1180          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1181              return true;                                                                                          
1182          }                                                                                                         
1183                                                                                                                    
1184          return handled;                                                                                           
1185      }                                                                                                             
1186                                                                                                                    
1187      private String getTypedText() {                                                                               
1188          return mDefaultKeySsb.toString();                                                                         
1189      }                                                                                                             
1190                                                                                                                    
1191      private void clearTypedText() {                                                                               
1192          mDefaultKeySsb.clear();                                                                                   
1193          mDefaultKeySsb.clearSpans();                                                                              
1194          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1195      }                                                                                                             
1196                                                                                                                    
1197      /**                                                                                                           
1198       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1199       * State                                                                                                      
1200       */                                                                                                           
1201      private static State intToState(int stateOrdinal) {                                                           
1202          State state = State.WORKSPACE;                                                                            
1203          final State[] stateValues = State.values();                                                               
1204          for (int i = 0; i < stateValues.length; i++) {                                                            
1205              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1206                  state = stateValues[i];                                                                           
1207                  break;                                                                                            
1208              }                                                                                                     
1209          }                                                                                                         
1210          return state;                                                                                             
1211      }                                                                                                             
1212                                                                                                                    
1213      /**                                                                                                           
1214       * Restores the previous state, if it exists.                                                                 
1215       *                                                                                                            
1216       * @param savedState The previous state.                                                                      
1217       */                                                                                                           
1218      @SuppressWarnings("unchecked")                                                                                
1219      private void restoreState(Bundle savedState) {                                                                
1220          if (savedState == null) {                                                                                 
1221              return;                                                                                               
1222          }                                                                                                         
1223                                                                                                                    
1224          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1225          if (state == State.APPS_CUSTOMIZE) {                                                                      
1226              mOnResumeState = State.APPS_CUSTOMIZE;                                                                
1227          }                                                                                                         
1228                                                                                                                    
1229          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1230                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1231          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1232              mWorkspace.setRestorePage(currentScreen);                                                             
1233          }                                                                                                         
1234                                                                                                                    
1235          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1236          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1237                                                                                                                    
1238          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1239              mPendingAddInfo.container = pendingAddContainer;                                                      
1240              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1241              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1242              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1243              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1244              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1245              mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);              
1246              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1247              setWaitingForResult(true);                                                                            
1248              mRestoring = true;                                                                                    
1249          }                                                                                                         
1250                                                                                                                    
1251          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1252          if (renameFolder) {                                                                                       
1253              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1254              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1255              mRestoring = true;                                                                                    
1256          }                                                                                                         
1257                                                                                                                    
1258          // Restore the AppsCustomize tab                                                                          
1259          if (mAppsCustomizeTabHost != null) {                                                                      
1260              String curTab = savedState.getString("apps_customize_currentTab");                                    
1261              if (curTab != null) {                                                                                 
1262                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1263                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1264                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1265                          mAppsCustomizeContent.getCurrentPage());                                                  
1266              }                                                                                                     
1267                                                                                                                    
1268              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1269              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1270          }                                                                                                         
1271          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1272                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1273      }                                                                                                             
1274                                                                                                                    
1275      /**                                                                                                           
1276       * Finds all the views we need and configure them properly.                                                   
1277       */                                                                                                           
1278      private void setupViews() {                                                                                   
1279          final DragController dragController = mDragController;                                                    
1280                                                                                                                    
1281          mLauncherView = findViewById(R.id.launcher);                                                              
1282          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1283          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1284          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1285          mWorkspace.setPageSwitchListener(this);                                                                   
1286          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1287                                                                                                                    
1288          mLauncherView.setSystemUiVisibility(                                                                      
1289                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1290          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1291                                                                                                                    
1292          // Setup the drag layer                                                                                   
1293          mDragLayer.setup(this, dragController);                                                                   
1294                                                                                                                    
1295          // Setup the hotseat                                                                                      
1296          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1297          if (mHotseat != null) {                                                                                   
1298              mHotseat.setup(this);                                                                                 
1299              mHotseat.setOnLongClickListener(this);                                                                
1300          }                                                                                                         
1301                                                                                                                    
1302          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1303          View widgetButton = findViewById(R.id.widget_button);                                                     
1304          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1305              @Override                                                                                             
1306              public void onClick(View arg0) {                                                                      
1307                  if (!mWorkspace.isSwitchingState()) {                                                             
1308                      onClickAddWidgetButton(arg0);                                                                 
1309                  }                                                                                                 
1310              }                                                                                                     
1311          });                                                                                                       
1312          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1313                                                                                                                    
1314          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1315          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1316              @Override                                                                                             
1317              public void onClick(View arg0) {                                                                      
1318                  if (!mWorkspace.isSwitchingState()) {                                                             
1319                      onClickWallpaperPicker(arg0);                                                                 
1320                  }                                                                                                 
1321              }                                                                                                     
1322          });                                                                                                       
1323          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1324                                                                                                                    
1325          View settingsButton = findViewById(R.id.settings_button);                                                 
1326          if (hasSettings()) {                                                                                      
1327              settingsButton.setOnClickListener(new OnClickListener() {                                             
1328                  @Override                                                                                         
1329                  public void onClick(View arg0) {                                                                  
1330                      if (!mWorkspace.isSwitchingState()) {                                                         
1331                          onClickSettingsButton(arg0);                                                              
1332                      }                                                                                             
1333                  }                                                                                                 
1334              });                                                                                                   
1335              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1336          } else {                                                                                                  
1337              settingsButton.setVisibility(View.GONE);                                                              
1338              FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();              
1339              lp.gravity = Gravity.END | Gravity.TOP;                                                               
1340              widgetButton.requestLayout();                                                                         
1341          }                                                                                                         
1342                                                                                                                    
1343          mOverviewPanel.setAlpha(0f);                                                                              
1344                                                                                                                    
1345          // Setup the workspace                                                                                    
1346          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1347          mWorkspace.setOnLongClickListener(this);                                                                  
1348          mWorkspace.setup(dragController);                                                                         
1349          dragController.addDragListener(mWorkspace);                                                               
1350                                                                                                                    
1351          // Get the search/delete bar                                                                              
1352          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1353                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1354                                                                                                                    
1355          // Setup AppsCustomize                                                                                    
1356          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1357          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1358                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1359          mAppsCustomizeContent.setup(this, dragController);                                                        
1360                                                                                                                    
1361          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1362          dragController.setDragScoller(mWorkspace);                                                                
1363          dragController.setScrollView(mDragLayer);                                                                 
1364          dragController.setMoveTarget(mWorkspace);                                                                 
1365          dragController.addDropTarget(mWorkspace);                                                                 
1366          if (mSearchDropTargetBar != null) {                                                                       
1367              mSearchDropTargetBar.setup(this, dragController);                                                     
1368          }                                                                                                         
1369                                                                                                                    
1370          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1371              Log.v(TAG, "adding WeightWatcher");                                                                   
1372              mWeightWatcher = new WeightWatcher(this);                                                             
1373              mWeightWatcher.setAlpha(0.5f);                                                                        
1374              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1375                      new FrameLayout.LayoutParams(                                                                 
1376                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1377                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1378                              Gravity.BOTTOM)                                                                       
1379              );                                                                                                    
1380                                                                                                                    
1381              boolean show = shouldShowWeightWatcher();                                                             
1382              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1383          }                                                                                                         
1384      }                                                                                                             
1385                                                                                                                    
1386      /**                                                                                                           
1387       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1388       */                                                                                                           
1389      public void setAllAppsButton(View allAppsButton) {                                                            
1390          mAllAppsButton = allAppsButton;                                                                           
1391      }                                                                                                             
1392                                                                                                                    
1393      public View getAllAppsButton() {                                                                              
1394          return mAllAppsButton;                                                                                    
1395      }                                                                                                             
1396                                                                                                                    
1397      /**                                                                                                           
1398       * Creates a view representing a shortcut.                                                                    
1399       *                                                                                                            
1400       * @param info The data structure describing the shortcut.                                                    
1401       *                                                                                                            
1402       * @return A View inflated from R.layout.application.                                                         
1403       */                                                                                                           
1404      View createShortcut(ShortcutInfo info) {                                                                      
1405          return createShortcut(R.layout.application,                                                               
1406                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1407      }                                                                                                             
1408                                                                                                                    
1409      /**                                                                                                           
1410       * Creates a view representing a shortcut inflated from the specified resource.                               
1411       *                                                                                                            
1412       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1413       * @param parent The group the shortcut belongs to.                                                           
1414       * @param info The data structure describing the shortcut.                                                    
1415       *                                                                                                            
1416       * @return A View inflated from layoutResId.                                                                  
1417       */                                                                                                           
1418      View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                                   
1419          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1420          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1421          favorite.setOnClickListener(this);                                                                        
1422          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1423          return favorite;                                                                                          
1424      }                                                                                                             
1425                                                                                                                    
1426      /**                                                                                                           
1427       * Add a shortcut to the workspace.                                                                           
1428       *                                                                                                            
1429       * @param data The intent describing the shortcut.                                                            
1430       * @param cellInfo The position on screen where to create the shortcut.                                       
1431       */                                                                                                           
1432      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1433              int cellY) {                                                                                          
1434          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1435          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1436          CellLayout layout = getCellLayout(container, screenId);                                                   
1437                                                                                                                    
1438          boolean foundCellSpan = false;                                                                            
1439                                                                                                                    
1440          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                                      
1441          if (info == null) {                                                                                       
1442              return;                                                                                               
1443          }                                                                                                         
1444          final View view = createShortcut(info);                                                                   
1445                                                                                                                    
1446          // First we check if we already know the exact location where we want to add this item.                   
1447          if (cellX >= 0 && cellY >= 0) {                                                                           
1448              cellXY[0] = cellX;                                                                                    
1449              cellXY[1] = cellY;                                                                                    
1450              foundCellSpan = true;                                                                                 
1451                                                                                                                    
1452              // If appropriate, either create a folder or add to an existing folder                                
1453              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1454                      true, null,null)) {                                                                           
1455                  return;                                                                                           
1456              }                                                                                                     
1457              DragObject dragObject = new DragObject();                                                             
1458              dragObject.dragInfo = info;                                                                           
1459              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1460                      true)) {                                                                                      
1461                  return;                                                                                           
1462              }                                                                                                     
1463          } else if (touchXY != null) {                                                                             
1464              // when dragging and dropping, just find the closest free spot                                        
1465              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1466              foundCellSpan = (result != null);                                                                     
1467          } else {                                                                                                  
1468              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1469          }                                                                                                         
1470                                                                                                                    
1471          if (!foundCellSpan) {                                                                                     
1472              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1473              return;                                                                                               
1474          }                                                                                                         
1475                                                                                                                    
1476          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1477                                                                                                                    
1478          if (!mRestoring) {                                                                                        
1479              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1480                      isWorkspaceLocked());                                                                         
1481          }                                                                                                         
1482      }                                                                                                             
1483                                                                                                                    
1484      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1485              int minHeight) {                                                                                      
1486          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1487          // We want to account for the extra amount of padding that we are adding to the widget                    
1488          // to ensure that it gets the full amount of space that it has requested                                  
1489          int requiredWidth = minWidth + padding.left + padding.right;                                              
1490          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1491          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1492      }                                                                                                             
1493                                                                                                                    
1494      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1495          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1496      }                                                                                                             
1497                                                                                                                    
1498      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1499          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1500      }                                                                                                             
1501                                                                                                                    
1502      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1503          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1504      }                                                                                                             
1505                                                                                                                    
1506      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1507          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1508                  info.minResizeHeight);                                                                            
1509      }                                                                                                             
1510                                                                                                                    
1511      /**                                                                                                           
1512       * Add a widget to the workspace.                                                                             
1513       *                                                                                                            
1514       * @param appWidgetId The app widget id                                                                       
1515       * @param cellInfo The position on screen where to create the widget.                                         
1516       */                                                                                                           
1517      private void completeAddAppWidget(final int appWidgetId, long container, long screenId,                       
1518              AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                                    
1519          if (appWidgetInfo == null) {                                                                              
1520              appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                                      
1521          }                                                                                                         
1522                                                                                                                    
1523          // Calculate the grid spans needed to fit this widget                                                     
1524          CellLayout layout = getCellLayout(container, screenId);                                                   
1525                                                                                                                    
1526          int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                               
1527          int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                                     
1528                                                                                                                    
1529          // Try finding open space on Launcher screen                                                              
1530          // We have saved the position to which the widget was dragged-- this really only matters                  
1531          // if we are placing widgets on a "spring-loaded" screen                                                  
1532          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1533          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1534          int[] finalSpan = new int[2];                                                                             
1535          boolean foundCellSpan = false;                                                                            
1536          if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                           
1537              cellXY[0] = mPendingAddInfo.cellX;                                                                    
1538              cellXY[1] = mPendingAddInfo.cellY;                                                                    
1539              spanXY[0] = mPendingAddInfo.spanX;                                                                    
1540              spanXY[1] = mPendingAddInfo.spanY;                                                                    
1541              foundCellSpan = true;                                                                                 
1542          } else if (touchXY != null) {                                                                             
1543              // when dragging and dropping, just find the closest free spot                                        
1544              int[] result = layout.findNearestVacantArea(                                                          
1545                      touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                                
1546                      spanXY[1], cellXY, finalSpan);                                                                
1547              spanXY[0] = finalSpan[0];                                                                             
1548              spanXY[1] = finalSpan[1];                                                                             
1549              foundCellSpan = (result != null);                                                                     
1550          } else {                                                                                                  
1551              foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                           
1552          }                                                                                                         
1553                                                                                                                    
1554          if (!foundCellSpan) {                                                                                     
1555              if (appWidgetId != -1) {                                                                              
1556                  // Deleting an app widget ID is a void call but writes to disk before returning                   
1557                  // to the caller...                                                                               
1558                  new AsyncTask<Void, Void, Void>() {                                                               
1559                      public Void doInBackground(Void ... args) {                                                   
1560                          mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                            
1561                          return null;                                                                              
1562                      }                                                                                             
1563                  }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                 
1564              }                                                                                                     
1565              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1566              return;                                                                                               
1567          }                                                                                                         
1568                                                                                                                    
1569          // Build Launcher-specific widget info and save to database                                               
1570          LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                               
1571                  appWidgetInfo.provider);                                                                          
1572          launcherInfo.spanX = spanXY[0];                                                                           
1573          launcherInfo.spanY = spanXY[1];                                                                           
1574          launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                         
1575          launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                         
1576          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1577                                                                                                                    
1578          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1579                  container, screenId, cellXY[0], cellXY[1], false);                                                
1580                                                                                                                    
1581          if (!mRestoring) {                                                                                        
1582              if (hostView == null) {                                                                               
1583                  // Perform actual inflation because we're live                                                    
1584                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);              
1585                  launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                                   
1586              } else {                                                                                              
1587                  // The AppWidgetHostView has already been inflated and instantiated                               
1588                  launcherInfo.hostView = hostView;                                                                 
1589              }                                                                                                     
1590                                                                                                                    
1591              launcherInfo.hostView.setTag(launcherInfo);                                                           
1592              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1593              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1594                                                                                                                    
1595              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],              
1596                      launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                                 
1597                                                                                                                    
1598              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1599          }                                                                                                         
1600          resetAddInfo();                                                                                           
1601      }                                                                                                             
1602                                                                                                                    
1603      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1604          @Override                                                                                                 
1605          public void onReceive(Context context, Intent intent) {                                                   
1606              final String action = intent.getAction();                                                             
1607              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1608                  mUserPresent = false;                                                                             
1609                  mDragLayer.clearAllResizeFrames();                                                                
1610                  updateRunning();                                                                                  
1611                                                                                                                    
1612                  // Reset AllApps to its initial state only if we are not in the middle of                         
1613                  // processing a multi-step drop                                                                   
1614                  if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               
1615                      showWorkspace(false);                                                                         
1616                  }                                                                                                 
1617              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1618                  mUserPresent = true;                                                                              
1619                  updateRunning();                                                                                  
1620              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1621                  mModel.resetLoadedState(false, true);                                                             
1622                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1623                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1624              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1625                  mModel.resetLoadedState(false, true);                                                             
1626                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1627                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1628                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1629              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1630                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1631                  getModel().forceReload();                                                                         
1632              }                                                                                                     
1633          }                                                                                                         
1634      };                                                                                                            
1635                                                                                                                    
1636      @Override                                                                                                     
1637      public void onAttachedToWindow() {                                                                            
1638          super.onAttachedToWindow();                                                                               
1639                                                                                                                    
1640          // Listen for broadcasts related to user-presence                                                         
1641          final IntentFilter filter = new IntentFilter();                                                           
1642          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1643          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1644          // For handling managed profiles                                                                          
1645          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1646          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1647          if (ENABLE_DEBUG_INTENTS) {                                                                               
1648              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1649              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1650          }                                                                                                         
1651          registerReceiver(mReceiver, filter);                                                                      
1652          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1653          setupTransparentSystemBarsForLmp();                                                                       
1654          mAttached = true;                                                                                         
1655          mVisible = true;                                                                                          
1656      }                                                                                                             
1657                                                                                                                    
1658      /**                                                                                                           
1659       * Sets up transparent navigation and status bars in LMP.                                                     
1660       * This method is a no-op for other platform versions.                                                        
1661       */                                                                                                           
1662      @TargetApi(19)                                                                                                
1663      private void setupTransparentSystemBarsForLmp() {                                                             
1664          // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1665          // Currently we use reflection to access the flags and the API to set the transparency                    
1666          // on the System bars.                                                                                    
1667          if (Utilities.isLmpOrAbove()) {                                                                           
1668              try {                                                                                                 
1669                  getWindow().getAttributes().systemUiVisibility |=                                                 
1670                          (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1671                                  | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1672                                  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1673                  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1674                          | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1675                  Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1676                          "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1677                  getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1678                                                                                                                    
1679                  Method setStatusBarColorMethod =                                                                  
1680                          Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1681                  Method setNavigationBarColorMethod =                                                              
1682                          Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1683                  setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1684                  setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1685              } catch (NoSuchFieldException e) {                                                                    
1686                  Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1687              } catch (NoSuchMethodException ex) {                                                                  
1688                  Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1689              } catch (IllegalAccessException e) {                                                                  
1690                  Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1691              } catch (IllegalArgumentException e) {                                                                
1692                  Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1693              } catch (InvocationTargetException e) {                                                               
1694                  Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1695              } finally {}                                                                                          
1696          }                                                                                                         
1697      }                                                                                                             
1698                                                                                                                    
1699      @Override                                                                                                     
1700      public void onDetachedFromWindow() {                                                                          
1701          super.onDetachedFromWindow();                                                                             
1702          mVisible = false;                                                                                         
1703                                                                                                                    
1704          if (mAttached) {                                                                                          
1705              unregisterReceiver(mReceiver);                                                                        
1706              mAttached = false;                                                                                    
1707          }                                                                                                         
1708          updateRunning();                                                                                          
1709      }                                                                                                             
1710                                                                                                                    
1711      public void onWindowVisibilityChanged(int visibility) {                                                       
1712          mVisible = visibility == View.VISIBLE;                                                                    
1713          updateRunning();                                                                                          
1714          // The following code used to be in onResume, but it turns out onResume is called when                    
1715          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1716          // is a more appropriate event to handle                                                                  
1717          if (mVisible) {                                                                                           
1718              mAppsCustomizeTabHost.onWindowVisible();                                                              
1719              if (!mWorkspaceLoading) {                                                                             
1720                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1721                  // We want to let Launcher draw itself at least once before we force it to build                  
1722                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1723                  // apps is nice and speedy.                                                                       
1724                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1725                      private boolean mStarted = false;                                                             
1726                      public void onDraw() {                                                                        
1727                          if (mStarted) return;                                                                     
1728                          mStarted = true;                                                                          
1729                          // We delay the layer building a bit in order to give                                     
1730                          // other message processing a time to run.  In particular                                 
1731                          // this avoids a delay in hiding the IME if it was                                        
1732                          // currently shown, because doing that may involve                                        
1733                          // some communication back with the app.                                                  
1734                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1735                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1736                          mWorkspace.post(new Runnable() {                                                          
1737                                  public void run() {                                                               
1738                                      if (mWorkspace != null &&                                                     
1739                                              mWorkspace.getViewTreeObserver() != null) {                           
1740                                          mWorkspace.getViewTreeObserver().                                         
1741                                                  removeOnDrawListener(listener);                                   
1742                                      }                                                                             
1743                                  }                                                                                 
1744                              });                                                                                   
1745                          return;                                                                                   
1746                      }                                                                                             
1747                  });                                                                                               
1748              }                                                                                                     
1749              clearTypedText();                                                                                     
1750          }                                                                                                         
1751      }                                                                                                             
1752                                                                                                                    
1753      private void sendAdvanceMessage(long delay) {                                                                 
1754          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1755          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1756          mHandler.sendMessageDelayed(msg, delay);                                                                  
1757          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1758      }                                                                                                             
1759                                                                                                                    
1760      private void updateRunning() {                                                                                
1761          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1762          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1763              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1764              if (autoAdvanceRunning) {                                                                             
1765                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1766                  sendAdvanceMessage(delay);                                                                        
1767              } else {                                                                                              
1768                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1769                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1770                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1771                  }                                                                                                 
1772                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1773                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1774              }                                                                                                     
1775          }                                                                                                         
1776      }                                                                                                             
1777                                                                                                                    
1778      private final Handler mHandler = new Handler() {                                                              
1779          @Override                                                                                                 
1780          public void handleMessage(Message msg) {                                                                  
1781              if (msg.what == ADVANCE_MSG) {                                                                        
1782                  int i = 0;                                                                                        
1783                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1784                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1785                      final int delay = mAdvanceStagger * i;                                                        
1786                      if (v instanceof Advanceable) {                                                               
1787                         postDelayed(new Runnable() {                                                               
1788                             public void run() {                                                                    
1789                                 ((Advanceable) v).advance();                                                       
1790                             }                                                                                      
1791                         }, delay);                                                                                 
1792                      }                                                                                             
1793                      i++;                                                                                          
1794                  }                                                                                                 
1795                  sendAdvanceMessage(mAdvanceInterval);                                                             
1796              }                                                                                                     
1797          }                                                                                                         
1798      };                                                                                                            
1799                                                                                                                    
1800      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1801          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1802          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1803          if (v instanceof Advanceable) {                                                                           
1804              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1805              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1806              updateRunning();                                                                                      
1807          }                                                                                                         
1808      }                                                                                                             
1809                                                                                                                    
1810      void removeWidgetToAutoAdvance(View hostView) {                                                               
1811          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1812              mWidgetsToAdvance.remove(hostView);                                                                   
1813              updateRunning();                                                                                      
1814          }                                                                                                         
1815      }                                                                                                             
1816                                                                                                                    
1817      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1818          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1819          launcherInfo.hostView = null;                                                                             
1820      }                                                                                                             
1821                                                                                                                    
1822      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
1823          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1824          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1825      }                                                                                                             
1826                                                                                                                    
1827      public DragLayer getDragLayer() {                                                                             
1828          return mDragLayer;                                                                                        
1829      }                                                                                                             
1830                                                                                                                    
1831      public Workspace getWorkspace() {                                                                             
1832          return mWorkspace;                                                                                        
1833      }                                                                                                             
1834                                                                                                                    
1835      public Hotseat getHotseat() {                                                                                 
1836          return mHotseat;                                                                                          
1837      }                                                                                                             
1838                                                                                                                    
1839      public ViewGroup getOverviewPanel() {                                                                         
1840          return mOverviewPanel;                                                                                    
1841      }                                                                                                             
1842                                                                                                                    
1843      public SearchDropTargetBar getSearchBar() {                                                                   
1844          return mSearchDropTargetBar;                                                                              
1845      }                                                                                                             
1846                                                                                                                    
1847      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
1848          return mAppWidgetHost;                                                                                    
1849      }                                                                                                             
1850                                                                                                                    
1851      public LauncherModel getModel() {                                                                             
1852          return mModel;                                                                                            
1853      }                                                                                                             
1854                                                                                                                    
1855      protected SharedPreferences getSharedPrefs() {                                                                
1856          return mSharedPrefs;                                                                                      
1857      }                                                                                                             
1858                                                                                                                    
1859      public void closeSystemDialogs() {                                                                            
1860          getWindow().closeAllPanels();                                                                             
1861                                                                                                                    
1862          // Whatever we were doing is hereby canceled.                                                             
1863          setWaitingForResult(false);                                                                               
1864      }                                                                                                             
1865                                                                                                                    
1866      @Override                                                                                                     
1867      protected void onNewIntent(Intent intent) {                                                                   
1868          long startTime = 0;                                                                                       
1869          if (DEBUG_RESUME_TIME) {                                                                                  
1870              startTime = System.currentTimeMillis();                                                               
1871          }                                                                                                         
1872          super.onNewIntent(intent);                                                                                
1873                                                                                                                    
1874          // Close the menu                                                                                         
1875          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
1876              // also will cancel mWaitingForResult.                                                                
1877              closeSystemDialogs();                                                                                 
1878                                                                                                                    
1879              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
1880                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
1881                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
1882                                                                                                                    
1883              if (mWorkspace == null) {                                                                             
1884                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
1885                  return;                                                                                           
1886              }                                                                                                     
1887              Folder openFolder = mWorkspace.getOpenFolder();                                                       
1888              // In all these cases, only animate if we're already on home                                          
1889              mWorkspace.exitWidgetResizeMode();                                                                    
1890              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
1891                      openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                              
1892                  mWorkspace.moveToDefaultScreen(true);                                                             
1893              }                                                                                                     
1894                                                                                                                    
1895              closeFolder();                                                                                        
1896              exitSpringLoadedDragMode();                                                                           
1897                                                                                                                    
1898              // If we are already on home, then just animate back to the workspace,                                
1899              // otherwise, just wait until onResume to set the state back to Workspace                             
1900              if (alreadyOnHome) {                                                                                  
1901                  showWorkspace(true);                                                                              
1902              } else {                                                                                              
1903                  mOnResumeState = State.WORKSPACE;                                                                 
1904              }                                                                                                     
1905                                                                                                                    
1906              final View v = getWindow().peekDecorView();                                                           
1907              if (v != null && v.getWindowToken() != null) {                                                        
1908                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
1909                          INPUT_METHOD_SERVICE);                                                                    
1910                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
1911              }                                                                                                     
1912                                                                                                                    
1913              // Reset the apps customize page                                                                      
1914              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
1915                  mAppsCustomizeTabHost.reset();                                                                    
1916              }                                                                                                     
1917                                                                                                                    
1918              onHomeIntent();                                                                                       
1919          }                                                                                                         
1920                                                                                                                    
1921          if (DEBUG_RESUME_TIME) {                                                                                  
1922              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
1923          }                                                                                                         
1924      }                                                                                                             
1925                                                                                                                    
1926      /**                                                                                                           
1927       * Override point for subclasses to prevent movement to the default screen when the home                      
1928       * button is pressed. Used (for example) in GEL, to prevent movement during a search.                         
1929       */                                                                                                           
1930      protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                                   
1931          return true;                                                                                              
1932      }                                                                                                             
1933                                                                                                                    
1934      /**                                                                                                           
1935       * Override point for subclasses to provide custom behaviour for when a home intent is fired.                 
1936       */                                                                                                           
1937      protected void onHomeIntent() {                                                                               
1938          // Do nothing                                                                                             
1939      }                                                                                                             
1940                                                                                                                    
1941      @Override                                                                                                     
1942      public void onRestoreInstanceState(Bundle state) {                                                            
1943          super.onRestoreInstanceState(state);                                                                      
1944          for (int page: mSynchronouslyBoundPages) {                                                                
1945              mWorkspace.restoreInstanceStateForChild(page);                                                        
1946          }                                                                                                         
1947      }                                                                                                             
1948                                                                                                                    
1949      @Override                                                                                                     
1950      protected void onSaveInstanceState(Bundle outState) {                                                         
1951          if (mWorkspace.getChildCount() > 0) {                                                                     
1952              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
1953                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
1954          }                                                                                                         
1955          super.onSaveInstanceState(outState);                                                                      
1956                                                                                                                    
1957          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
1958          // We close any open folder since it will not be re-opened, and we need to make sure                      
1959          // this state is reflected.                                                                               
1960          closeFolder();                                                                                            
1961                                                                                                                    
1962          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
1963                  mWaitingForResult) {                                                                              
1964              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
1965              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
1966              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
1967              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
1968              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
1969              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
1970              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
1971              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
1972          }                                                                                                         
1973                                                                                                                    
1974          if (mFolderInfo != null && mWaitingForResult) {                                                           
1975              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
1976              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
1977          }                                                                                                         
1978                                                                                                                    
1979          // Save the current AppsCustomize tab                                                                     
1980          if (mAppsCustomizeTabHost != null) {                                                                      
1981              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
1982              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
1983              if (currentTabTag != null) {                                                                          
1984                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
1985              }                                                                                                     
1986              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
1987              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
1988          }                                                                                                         
1989          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
1990      }                                                                                                             
1991                                                                                                                    
1992      @Override                                                                                                     
1993      public void onDestroy() {                                                                                     
1994          super.onDestroy();                                                                                        
1995                                                                                                                    
1996          // Remove all pending runnables                                                                           
1997          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1998          mHandler.removeMessages(0);                                                                               
1999          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2000                                                                                                                    
2001          // Stop callbacks from LauncherModel                                                                      
2002          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2003                                                                                                                    
2004          // It's possible to receive onDestroy after a new Launcher activity has                                   
2005          // been created. In this case, don't interfere with the new Launcher.                                     
2006          if (mModel.isCurrentCallbacks(this)) {                                                                    
2007              mModel.stopLoader();                                                                                  
2008              app.setLauncher(null);                                                                                
2009          }                                                                                                         
2010                                                                                                                    
2011          try {                                                                                                     
2012              mAppWidgetHost.stopListening();                                                                       
2013          } catch (NullPointerException ex) {                                                                       
2014              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2015          }                                                                                                         
2016          mAppWidgetHost = null;                                                                                    
2017                                                                                                                    
2018          mWidgetsToAdvance.clear();                                                                                
2019                                                                                                                    
2020          TextKeyListener.getInstance().release();                                                                  
2021                                                                                                                    
2022          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2023          // to prevent leaking Launcher activities on orientation change.                                          
2024          if (mModel != null) {                                                                                     
2025              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2026          }                                                                                                         
2027                                                                                                                    
2028          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2029          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2030                                                                                                                    
2031          mDragLayer.clearAllResizeFrames();                                                                        
2032          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2033          mWorkspace.removeAllWorkspaceScreens();                                                                   
2034          mWorkspace = null;                                                                                        
2035          mDragController = null;                                                                                   
2036                                                                                                                    
2037          PackageInstallerCompat.getInstance(this).onStop();                                                        
2038          LauncherAnimUtils.onDestroyActivity();                                                                    
2039      }                                                                                                             
2040                                                                                                                    
2041      public DragController getDragController() {                                                                   
2042          return mDragController;                                                                                   
2043      }                                                                                                             
2044                                                                                                                    
2045      @Override                                                                                                     
2046      public void startActivityForResult(Intent intent, int requestCode) {                                          
2047          if (requestCode >= 0) {                                                                                   
2048              setWaitingForResult(true);                                                                            
2049          }                                                                                                         
2050          super.startActivityForResult(intent, requestCode);                                                        
2051      }                                                                                                             
2052                                                                                                                    
2053      /**                                                                                                           
2054       * Indicates that we want global search for this activity by setting the globalSearch                         
2055       * argument for {@link #startSearch} to true.                                                                 
2056       */                                                                                                           
2057      @Override                                                                                                     
2058      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2059              Bundle appSearchData, boolean globalSearch) {                                                         
2060                                                                                                                    
2061          showWorkspace(true);                                                                                      
2062                                                                                                                    
2063          if (initialQuery == null) {                                                                               
2064              // Use any text typed in the launcher as the initial query                                            
2065              initialQuery = getTypedText();                                                                        
2066          }                                                                                                         
2067          if (appSearchData == null) {                                                                              
2068              appSearchData = new Bundle();                                                                         
2069              appSearchData.putString("source", "launcher-search");                                                 
2070          }                                                                                                         
2071          Rect sourceBounds = new Rect();                                                                           
2072          if (mSearchDropTargetBar != null) {                                                                       
2073              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2074          }                                                                                                         
2075                                                                                                                    
2076          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2077                  appSearchData, sourceBounds);                                                                     
2078          if (clearTextImmediately) {                                                                               
2079              clearTypedText();                                                                                     
2080          }                                                                                                         
2081      }                                                                                                             
2082                                                                                                                    
2083      /**                                                                                                           
2084       * Start a text search.                                                                                       
2085       *                                                                                                            
2086       * @return {@code true} if the search will start immediately, so any further keypresses                       
2087       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2088       * to buffer keypresses.                                                                                      
2089       */                                                                                                           
2090      public boolean startSearch(String initialQuery,                                                               
2091              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2092          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2093                  appSearchData, sourceBounds);                                                                     
2094          return false;                                                                                             
2095      }                                                                                                             
2096                                                                                                                    
2097      /**                                                                                                           
2098       * Starts the global search activity. This code is a copied from SearchManager                                
2099       */                                                                                                           
2100      private void startGlobalSearch(String initialQuery,                                                           
2101              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2102          final SearchManager searchManager =                                                                       
2103              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2104          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2105          if (globalSearchActivity == null) {                                                                       
2106              Log.w(TAG, "No global search activity found.");                                                       
2107              return;                                                                                               
2108          }                                                                                                         
2109          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2110          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2111          intent.setComponent(globalSearchActivity);                                                                
2112          // Make sure that we have a Bundle to put source in                                                       
2113          if (appSearchData == null) {                                                                              
2114              appSearchData = new Bundle();                                                                         
2115          } else {                                                                                                  
2116              appSearchData = new Bundle(appSearchData);                                                            
2117          }                                                                                                         
2118          // Set source to package name of app that starts global search, if not set already.                       
2119          if (!appSearchData.containsKey("source")) {                                                               
2120              appSearchData.putString("source", getPackageName());                                                  
2121          }                                                                                                         
2122          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2123          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2124              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2125          }                                                                                                         
2126          if (selectInitialQuery) {                                                                                 
2127              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2128          }                                                                                                         
2129          intent.setSourceBounds(sourceBounds);                                                                     
2130          try {                                                                                                     
2131              startActivity(intent);                                                                                
2132          } catch (ActivityNotFoundException ex) {                                                                  
2133              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2134          }                                                                                                         
2135      }                                                                                                             
2136                                                                                                                    
2137      public boolean isOnCustomContent() {                                                                          
2138          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2139      }                                                                                                             
2140                                                                                                                    
2141      @Override                                                                                                     
2142      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2143          super.onPrepareOptionsMenu(menu);                                                                         
2144          if (!isOnCustomContent()) {                                                                               
2145              // Close any open folders                                                                             
2146              closeFolder();                                                                                        
2147              // Stop resizing any widgets                                                                          
2148              mWorkspace.exitWidgetResizeMode();                                                                    
2149              if (!mWorkspace.isInOverviewMode()) {                                                                 
2150                  // Show the overview mode                                                                         
2151                  showOverviewMode(true);                                                                           
2152              } else {                                                                                              
2153                  showWorkspace(true);                                                                              
2154              }                                                                                                     
2155          }                                                                                                         
2156          return false;                                                                                             
2157      }                                                                                                             
2158                                                                                                                    
2159      @Override                                                                                                     
2160      public boolean onSearchRequested() {                                                                          
2161          startSearch(null, false, null, true);                                                                     
2162          // Use a custom animation for launching search                                                            
2163          return true;                                                                                              
2164      }                                                                                                             
2165                                                                                                                    
2166      public boolean isWorkspaceLocked() {                                                                          
2167          return mWorkspaceLoading || mWaitingForResult;                                                            
2168      }                                                                                                             
2169                                                                                                                    
2170      public boolean isWorkspaceLoading() {                                                                         
2171          return mWorkspaceLoading;                                                                                 
2172      }                                                                                                             
2173                                                                                                                    
2174      private void setWorkspaceLoading(boolean value) {                                                             
2175          boolean isLocked = isWorkspaceLocked();                                                                   
2176          mWorkspaceLoading = value;                                                                                
2177          if (isLocked != isWorkspaceLocked()) {                                                                    
2178              onWorkspaceLockedChanged();                                                                           
2179          }                                                                                                         
2180      }                                                                                                             
2181                                                                                                                    
2182      private void setWaitingForResult(boolean value) {                                                             
2183          boolean isLocked = isWorkspaceLocked();                                                                   
2184          mWaitingForResult = value;                                                                                
2185          if (isLocked != isWorkspaceLocked()) {                                                                    
2186              onWorkspaceLockedChanged();                                                                           
2187          }                                                                                                         
2188      }                                                                                                             
2189                                                                                                                    
2190      protected void onWorkspaceLockedChanged() { }                                                                 
2191                                                                                                                    
2192      private void resetAddInfo() {                                                                                 
2193          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2194          mPendingAddInfo.screenId = -1;                                                                            
2195          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2196          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2197          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2198          mPendingAddInfo.dropPos = null;                                                                           
2199      }                                                                                                             
2200                                                                                                                    
2201      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2202              final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {                     
2203          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2204      }                                                                                                             
2205                                                                                                                    
2206      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2207              final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int                   
2208              delay) {                                                                                              
2209          if (appWidgetInfo.configure != null) {                                                                    
2210              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2211              mPendingAddWidgetId = appWidgetId;                                                                    
2212                                                                                                                    
2213              // Launch over to configure widget, if needed                                                         
2214              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2215                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2216                                                                                                                    
2217          } else {                                                                                                  
2218              // Otherwise just add it                                                                              
2219              Runnable onComplete = new Runnable() {                                                                
2220                  @Override                                                                                         
2221                  public void run() {                                                                               
2222                      // Exit spring loaded mode if necessary after adding the widget                               
2223                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2224                              null);                                                                                
2225                  }                                                                                                 
2226              };                                                                                                    
2227              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2228                      appWidgetInfo);                                                                               
2229              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2230          }                                                                                                         
2231      }                                                                                                             
2232                                                                                                                    
2233      protected void moveToCustomContentScreen(boolean animate) {                                                   
2234          // Close any folders that may be open.                                                                    
2235          closeFolder();                                                                                            
2236          mWorkspace.moveToCustomContentScreen(animate);                                                            
2237      }                                                                                                             
2238      /**                                                                                                           
2239       * Process a shortcut drop.                                                                                   
2240       *                                                                                                            
2241       * @param componentName The name of the component                                                             
2242       * @param screenId The ID of the screen where it should be added                                              
2243       * @param cell The cell it should be added to, optional                                                       
2244       * @param position The location on the screen where it was dropped, optional                                  
2245       */                                                                                                           
2246      void processShortcutFromDrop(ComponentName componentName, long container, long screenId,                      
2247              int[] cell, int[] loc) {                                                                              
2248          resetAddInfo();                                                                                           
2249          mPendingAddInfo.container = container;                                                                    
2250          mPendingAddInfo.screenId = screenId;                                                                      
2251          mPendingAddInfo.dropPos = loc;                                                                            
2252                                                                                                                    
2253          if (cell != null) {                                                                                       
2254              mPendingAddInfo.cellX = cell[0];                                                                      
2255              mPendingAddInfo.cellY = cell[1];                                                                      
2256          }                                                                                                         
2257                                                                                                                    
2258          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2259          createShortcutIntent.setComponent(componentName);                                                         
2260          processShortcut(createShortcutIntent);                                                                    
2261      }                                                                                                             
2262                                                                                                                    
2263      /**                                                                                                           
2264       * Process a widget drop.                                                                                     
2265       *                                                                                                            
2266       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2267       * @param screenId The ID of the screen where it should be added                                              
2268       * @param cell The cell it should be added to, optional                                                       
2269       * @param position The location on the screen where it was dropped, optional                                  
2270       */                                                                                                           
2271      void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                           
2272              int[] cell, int[] span, int[] loc) {                                                                  
2273          resetAddInfo();                                                                                           
2274          mPendingAddInfo.container = info.container = container;                                                   
2275          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2276          mPendingAddInfo.dropPos = loc;                                                                            
2277          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2278          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2279                                                                                                                    
2280          if (cell != null) {                                                                                       
2281              mPendingAddInfo.cellX = cell[0];                                                                      
2282              mPendingAddInfo.cellY = cell[1];                                                                      
2283          }                                                                                                         
2284          if (span != null) {                                                                                       
2285              mPendingAddInfo.spanX = span[0];                                                                      
2286              mPendingAddInfo.spanY = span[1];                                                                      
2287          }                                                                                                         
2288                                                                                                                    
2289          AppWidgetHostView hostView = info.boundWidget;                                                            
2290          int appWidgetId;                                                                                          
2291          if (hostView != null) {                                                                                   
2292              appWidgetId = hostView.getAppWidgetId();                                                              
2293              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2294          } else {                                                                                                  
2295              // In this case, we either need to start an activity to get permission to bind                        
2296              // the widget, or we need to start an activity to configure the widget, or both.                      
2297              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2298              Bundle options = info.bindOptions;                                                                    
2299                                                                                                                    
2300              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2301                      appWidgetId, info.info, options);                                                             
2302              if (success) {                                                                                        
2303                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2304              } else {                                                                                              
2305                  mPendingAddWidgetInfo = info.info;                                                                
2306                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2307                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2308                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2309                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2310                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2311                  // TODO: we need to make sure that this accounts for the options bundle.                          
2312                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2313                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2314              }                                                                                                     
2315          }                                                                                                         
2316      }                                                                                                             
2317                                                                                                                    
2318      void processShortcut(Intent intent) {                                                                         
2319          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2320      }                                                                                                             
2321                                                                                                                    
2322      void processWallpaper(Intent intent) {                                                                        
2323          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2324      }                                                                                                             
2325                                                                                                                    
2326      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2327              int cellY) {                                                                                          
2328          final FolderInfo folderInfo = new FolderInfo();                                                           
2329          folderInfo.title = getText(R.string.folder_name);                                                         
2330                                                                                                                    
2331          // Update the model                                                                                       
2332          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2333                  false);                                                                                           
2334          sFolders.put(folderInfo.id, folderInfo);                                                                  
2335                                                                                                                    
2336          // Create the view                                                                                        
2337          FolderIcon newFolder =                                                                                    
2338              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2339          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2340                  isWorkspaceLocked());                                                                             
2341          // Force measure the new folder icon                                                                      
2342          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2343          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2344          return newFolder;                                                                                         
2345      }                                                                                                             
2346                                                                                                                    
2347      void removeFolder(FolderInfo folder) {                                                                        
2348          sFolders.remove(folder.id);                                                                               
2349      }                                                                                                             
2350                                                                                                                    
2351      protected ComponentName getWallpaperPickerComponent() {                                                       
2352          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2353      }                                                                                                             
2354                                                                                                                    
2355      /**                                                                                                           
2356       * Registers various content observers. The current implementation registers                                  
2357       * only a favorites observer to keep track of the favorites applications.                                     
2358       */                                                                                                           
2359      private void registerContentObservers() {                                                                     
2360          ContentResolver resolver = getContentResolver();                                                          
2361          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2362                  true, mWidgetObserver);                                                                           
2363      }                                                                                                             
2364                                                                                                                    
2365      @Override                                                                                                     
2366      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2367          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2368              switch (event.getKeyCode()) {                                                                         
2369                  case KeyEvent.KEYCODE_HOME:                                                                       
2370                      return true;                                                                                  
2371                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2372                      if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                                 
2373                          dumpState();                                                                              
2374                          return true;                                                                              
2375                      }                                                                                             
2376                      break;                                                                                        
2377              }                                                                                                     
2378          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2379              switch (event.getKeyCode()) {                                                                         
2380                  case KeyEvent.KEYCODE_HOME:                                                                       
2381                      return true;                                                                                  
2382              }                                                                                                     
2383          }                                                                                                         
2384                                                                                                                    
2385          return super.dispatchKeyEvent(event);                                                                     
2386      }                                                                                                             
2387                                                                                                                    
2388      @Override                                                                                                     
2389      public void onBackPressed() {                                                                                 
2390          if (isAllAppsVisible()) {                                                                                 
2391              if (mAppsCustomizeContent.getContentType() ==                                                         
2392                      AppsCustomizePagedView.ContentType.Applications) {                                            
2393                  showWorkspace(true);                                                                              
2394              } else {                                                                                              
2395                  showOverviewMode(true);                                                                           
2396              }                                                                                                     
2397          } else if (mWorkspace.isInOverviewMode()) {                                                               
2398              mWorkspace.exitOverviewMode(true);                                                                    
2399          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2400              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2401              if (openFolder.isEditingName()) {                                                                     
2402                  openFolder.dismissEditingName();                                                                  
2403              } else {                                                                                              
2404                  closeFolder();                                                                                    
2405              }                                                                                                     
2406          } else {                                                                                                  
2407              mWorkspace.exitWidgetResizeMode();                                                                    
2408                                                                                                                    
2409              // Back button is a no-op here, but give at least some feedback for the button press                  
2410              mWorkspace.showOutlinesTemporarily();                                                                 
2411          }                                                                                                         
2412      }                                                                                                             
2413                                                                                                                    
2414      /**                                                                                                           
2415       * Re-listen when widgets are reset.                                                                          
2416       */                                                                                                           
2417      private void onAppWidgetReset() {                                                                             
2418          if (mAppWidgetHost != null) {                                                                             
2419              mAppWidgetHost.startListening();                                                                      
2420          }                                                                                                         
2421      }                                                                                                             
2422                                                                                                                    
2423      /**                                                                                                           
2424       * Launches the intent referred by the clicked shortcut.                                                      
2425       *                                                                                                            
2426       * @param v The view representing the clicked shortcut.                                                       
2427       */                                                                                                           
2428      public void onClick(View v) {                                                                                 
2429          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2430          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2431          if (v.getWindowToken() == null) {                                                                         
2432              return;                                                                                               
2433          }                                                                                                         
2434                                                                                                                    
2435          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2436              return;                                                                                               
2437          }                                                                                                         
2438                                                                                                                    
2439          if (v instanceof Workspace) {                                                                             
2440              if (mWorkspace.isInOverviewMode()) {                                                                  
2441                  mWorkspace.exitOverviewMode(true);                                                                
2442              }                                                                                                     
2443              return;                                                                                               
2444          }                                                                                                         
2445                                                                                                                    
2446          if (v instanceof CellLayout) {                                                                            
2447              if (mWorkspace.isInOverviewMode()) {                                                                  
2448                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2449              }                                                                                                     
2450          }                                                                                                         
2451                                                                                                                    
2452          Object tag = v.getTag();                                                                                  
2453          if (tag instanceof ShortcutInfo) {                                                                        
2454              onClickAppShortcut(v);                                                                                
2455          } else if (tag instanceof FolderInfo) {                                                                   
2456              if (v instanceof FolderIcon) {                                                                        
2457                  onClickFolderIcon(v);                                                                             
2458              }                                                                                                     
2459          } else if (v == mAllAppsButton) {                                                                         
2460              onClickAllAppsButton(v);                                                                              
2461          } else if (tag instanceof AppInfo) {                                                                      
2462              startAppShortcutOrInfoActivity(v);                                                                    
2463          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2464              if (v instanceof PendingAppWidgetHostView) {                                                          
2465                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2466              }                                                                                                     
2467          }                                                                                                         
2468      }                                                                                                             
2469                                                                                                                    
2470      public void onClickPagedViewIcon(View v) {                                                                    
2471          startAppShortcutOrInfoActivity(v);                                                                        
2472      }                                                                                                             
2473                                                                                                                    
2474      public boolean onTouch(View v, MotionEvent event) {                                                           
2475          return false;                                                                                             
2476      }                                                                                                             
2477                                                                                                                    
2478      /**                                                                                                           
2479       * Event handler for the app widget view which has not fully restored.                                        
2480       */                                                                                                           
2481      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2482          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2483          if (v.isReadyForClickSetup()) {                                                                           
2484              int widgetId = info.appWidgetId;                                                                      
2485              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2486              if (appWidgetInfo != null) {                                                                          
2487                  mPendingAddWidgetInfo = appWidgetInfo;                                                            
2488                  mPendingAddInfo.copyFrom(info);                                                                   
2489                  mPendingAddWidgetId = widgetId;                                                                   
2490                                                                                                                    
2491                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2492                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2493              }                                                                                                     
2494          } else if (info.installProgress < 0) {                                                                    
2495              // The install has not been queued                                                                    
2496              final String packageName = info.providerName.getPackageName();                                        
2497              showBrokenAppInstallDialog(packageName,                                                               
2498                  new DialogInterface.OnClickListener() {                                                           
2499                      public void onClick(DialogInterface dialog, int id) {                                         
2500                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2501                      }                                                                                             
2502                  });                                                                                               
2503          } else {                                                                                                  
2504              // Download has started.                                                                              
2505              final String packageName = info.providerName.getPackageName();                                        
2506              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2507          }                                                                                                         
2508      }                                                                                                             
2509                                                                                                                    
2510      /**                                                                                                           
2511       * Event handler for the search button                                                                        
2512       *                                                                                                            
2513       * @param v The view that was clicked.                                                                        
2514       */                                                                                                           
2515      public void onClickSearchButton(View v) {                                                                     
2516          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2517                                                                                                                    
2518          onSearchRequested();                                                                                      
2519      }                                                                                                             
2520                                                                                                                    
2521      /**                                                                                                           
2522       * Event handler for the voice button                                                                         
2523       *                                                                                                            
2524       * @param v The view that was clicked.                                                                        
2525       */                                                                                                           
2526      public void onClickVoiceButton(View v) {                                                                      
2527          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2528                                                                                                                    
2529          startVoice();                                                                                             
2530      }                                                                                                             
2531                                                                                                                    
2532      public void startVoice() {                                                                                    
2533          try {                                                                                                     
2534              final SearchManager searchManager =                                                                   
2535                      (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                     
2536              ComponentName activityName = searchManager.getGlobalSearchActivity();                                 
2537              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
2538              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                       
2539              if (activityName != null) {                                                                           
2540                  intent.setPackage(activityName.getPackageName());                                                 
2541              }                                                                                                     
2542              startActivity(null, intent, "onClickVoiceButton");                                                    
2543          } catch (ActivityNotFoundException e) {                                                                   
2544              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
2545              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                       
2546              startActivitySafely(null, intent, "onClickVoiceButton");                                              
2547          }                                                                                                         
2548      }                                                                                                             
2549                                                                                                                    
2550      /**                                                                                                           
2551       * Event handler for the "grid" button that appears on the home screen, which                                 
2552       * enters all apps mode.                                                                                      
2553       *                                                                                                            
2554       * @param v The view that was clicked.                                                                        
2555       */                                                                                                           
2556      protected void onClickAllAppsButton(View v) {                                                                 
2557          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2558          if (isAllAppsVisible()) {                                                                                 
2559              showWorkspace(true);                                                                                  
2560          } else {                                                                                                  
2561              showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2562          }                                                                                                         
2563      }                                                                                                             
2564                                                                                                                    
2565      private void showBrokenAppInstallDialog(final String packageName,                                             
2566              DialogInterface.OnClickListener onSearchClickListener) {                                              
2567          new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))               

2568              .setTitle(R.string.abandoned_promises_title)                                                          
2569              .setMessage(R.string.abandoned_promise_explanation)                                                   
2570              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2571              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2572                  new DialogInterface.OnClickListener() {                                                           
2573                      public void onClick(DialogInterface dialog, int id) {                                         
2574                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2575                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2576                      }                                                                                             
2577                  })                                                                                                
2578              .create().show();                                                                                     
2579          return;                                                                                                   
2580      }                                                                                                             
2581                                                                                                                    
2582      /**                                                                                                           
2583       * Event handler for an app shortcut click.                                                                   
2584       *                                                                                                            
2585       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2586       */                                                                                                           
2587      protected void onClickAppShortcut(final View v) {                                                             
2588          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2589          Object tag = v.getTag();                                                                                  
2590          if (!(tag instanceof ShortcutInfo)) {                                                                     
2591              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2592          }                                                                                                         
2593                                                                                                                    
2594          // Open shortcut                                                                                          
2595          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         










2596          final Intent intent = shortcut.intent;                                                                    
2597                                                                                                                    
2598          // Check for special shortcuts                                                                            
2599          if (intent.getComponent() != null) {                                                                      
2600              final String shortcutClass = intent.getComponent().getClassName();                                    
2601                                                                                                                    
2602              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2603                  MemoryDumpActivity.startDump(this);                                                               
2604                  return;                                                                                           
2605              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2606                  toggleShowWeightWatcher();                                                                        
2607                  return;                                                                                           
2608              }                                                                                                     
2609          }                                                                                                         
2610                                                                                                                    
2611          // Check for abandoned promise                                                                            
2612          if ((v instanceof BubbleTextView)                                                                         
2613                  && shortcut.isPromise()                                                                           
2614                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2615              showBrokenAppInstallDialog(                                                                           
2616                      shortcut.getTargetComponent().getPackageName(),                                               
2617                      new DialogInterface.OnClickListener() {                                                       
2618                          public void onClick(DialogInterface dialog, int id) {                                     
2619                              startAppShortcutOrInfoActivity(v);                                                    
2620                          }                                                                                         
2621                      });                                                                                           
2622              return;                                                                                               
2623          }                                                                                                         
2624                                                                                                                    
2625          // Start activities                                                                                       
2626          startAppShortcutOrInfoActivity(v);                                                                        
2627      }                                                                                                             
2628                                                                                                                    
2629      private void startAppShortcutOrInfoActivity(View v) {                                                         
2630          Object tag = v.getTag();                                                                                  
2631          final ShortcutInfo shortcut;                                                                              
2632          final Intent intent;                                                                                      
2633          if (tag instanceof ShortcutInfo) {                                                                        
2634              shortcut = (ShortcutInfo) tag;                                                                        
2635              intent = shortcut.intent;                                                                             
2636              int[] pos = new int[2];                                                                               
2637              v.getLocationOnScreen(pos);                                                                           
2638              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2639                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2640                                                                                                                    
2641          } else if (tag instanceof AppInfo) {                                                                      
2642              shortcut = null;                                                                                      
2643              intent = ((AppInfo) tag).intent;                                                                      
2644          } else {                                                                                                  
2645              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2646          }                                                                                                         
2647                                                                                                                    
2648          boolean success = startActivitySafely(v, intent, tag);                                                    
2649          mStats.recordLaunch(intent, shortcut);                                                                    
2650                                                                                                                    
2651          if (success && v instanceof BubbleTextView) {                                                             
2652              mWaitingForResume = (BubbleTextView) v;                                                               
2653              mWaitingForResume.setStayPressed(true);                                                               
2654          }                                                                                                         
2655      }                                                                                                             
2656                                                                                                                    
2657      /**                                                                                                           
2658       * Event handler for a folder icon click.                                                                     
2659       *                                                                                                            
2660       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2661       */                                                                                                           
2662      protected void onClickFolderIcon(View v) {                                                                    
2663          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2664          if (!(v instanceof FolderIcon)){                                                                          
2665              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2666          }                                                                                                         
2667                                                                                                                    
2668          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2669          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2670          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2671                                                                                                                    
2672          // If the folder info reports that the associated folder is open, then verify that                        
2673          // it is actually opened. There have been a few instances where this gets out of sync.                    
2674          if (info.opened && openFolder == null) {                                                                  
2675              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2676                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2677              info.opened = false;                                                                                  
2678          }                                                                                                         
2679                                                                                                                    
2680          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2681              // Close any open folder                                                                              
2682              closeFolder();                                                                                        
2683              // Open the requested folder                                                                          
2684              openFolder(folderIcon);                                                                               
2685          } else {                                                                                                  
2686              // Find the open folder...                                                                            
2687              int folderScreen;                                                                                     
2688              if (openFolder != null) {                                                                             
2689                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2690                  // .. and close it                                                                                
2691                  closeFolder(openFolder);                                                                          
2692                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2693                      // Close any folder open on the current screen                                                
2694                      closeFolder();                                                                                
2695                      // Pull the folder onto this screen                                                           
2696                      openFolder(folderIcon);                                                                       
2697                  }                                                                                                 
2698              }                                                                                                     
2699          }                                                                                                         
2700      }                                                                                                             
2701                                                                                                                    
2702      /**                                                                                                           
2703       * Event handler for the (Add) Widgets button that appears after a long press                                 
2704       * on the home screen.                                                                                        
2705       */                                                                                                           
2706      protected void onClickAddWidgetButton(View view) {                                                            
2707          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2708          showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                      
2709      }                                                                                                             
2710                                                                                                                    
2711      /**                                                                                                           
2712       * Event handler for the wallpaper picker button that appears after a long press                              
2713       * on the home screen.                                                                                        
2714       */                                                                                                           
2715      protected void onClickWallpaperPicker(View v) {                                                               
2716          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2717          final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2718          pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2719          startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
2720      }                                                                                                             
2721                                                                                                                    
2722      /**                                                                                                           
2723       * Event handler for a click on the settings button that appears after a long press                           
2724       * on the home screen.                                                                                        
2725       */                                                                                                           
2726      protected void onClickSettingsButton(View v) {                                                                
2727          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2728      }                                                                                                             
2729                                                                                                                    
2730      public void onTouchDownAllAppsButton(View v) {                                                                
2731          // Provide the same haptic feedback that the system offers for virtual keys.                              
2732          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2733      }                                                                                                             
2734                                                                                                                    
2735      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2736          // Provide the same haptic feedback that the system offers for virtual keys.                              
2737          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2738      }                                                                                                             
2739                                                                                                                    
2740      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2741          if (mHapticFeedbackTouchListener == null) {                                                               
2742              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2743                  @Override                                                                                         
2744                  public boolean onTouch(View v, MotionEvent event) {                                               
2745                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2746                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2747                      }                                                                                             
2748                      return false;                                                                                 
2749                  }                                                                                                 
2750              };                                                                                                    
2751          }                                                                                                         
2752          return mHapticFeedbackTouchListener;                                                                      
2753      }                                                                                                             
2754                                                                                                                    
2755      public void onDragStarted(View view) {}                                                                       
2756                                                                                                                    
2757      /**                                                                                                           
2758       * Called when the user stops interacting with the launcher.                                                  
2759       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2760       */                                                                                                           
2761      protected void onInteractionEnd() {}                                                                          
2762                                                                                                                    
2763      /**                                                                                                           
2764       * Called when the user starts interacting with the launcher.                                                 
2765       * The possible interactions are:                                                                             
2766       *  - open all apps                                                                                           
2767       *  - reorder an app shortcut, or a widget                                                                    
2768       *  - open the overview mode.                                                                                 
2769       * This is a good time to stop doing things that only make sense                                              
2770       * when the user is on the homescreen and not doing housekeeping.                                             
2771       */                                                                                                           
2772      protected void onInteractionBegin() {}                                                                        
2773                                                                                                                    
2774      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
2775          String packageName = componentName.getPackageName();                                                      
2776          try {                                                                                                     
2777              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2778              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2779              launcherApps.showAppDetailsForProfile(componentName, user);                                           
2780          } catch (SecurityException e) {                                                                           
2781              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2782              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
2783          } catch (ActivityNotFoundException e) {                                                                   
2784              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2785              Log.e(TAG, "Unable to launch settings");                                                              
2786          }                                                                                                         
2787      }                                                                                                             
2788                                                                                                                    
2789      // returns true if the activity was started                                                                   
2790      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
2791              UserHandleCompat user) {                                                                              
2792          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2793              // System applications cannot be installed. For now, show a toast explaining that.                    
2794              // We may give them the option of disabling apps this way.                                            
2795              int messageId = R.string.uninstall_system_app_text;                                                   
2796              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2797              return false;                                                                                         
2798          } else {                                                                                                  
2799              String packageName = componentName.getPackageName();                                                  
2800              String className = componentName.getClassName();                                                      
2801              Intent intent = new Intent(                                                                           
2802                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
2803              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
2804                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
2805              if (user != null) {                                                                                   
2806                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
2807              }                                                                                                     
2808              startActivity(intent);                                                                                
2809              return true;                                                                                          
2810          }                                                                                                         
2811      }                                                                                                             
2812                                                                                                                    
2813      boolean startActivity(View v, Intent intent, Object tag) {                                                    
2814          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2815          try {                                                                                                     
2816              // Only launch using the new animation if the shortcut has not opted out (this is a                   
2817              // private contract between launcher and may be ignored in the future).                               
2818              boolean useLaunchAnimation = (v != null) &&                                                           
2819                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
2820              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2821              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2822                                                                                                                    
2823              UserHandleCompat user = null;                                                                         
2824              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
2825                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
2826                  user = userManager.getUserForSerialNumber(serialNumber);                                          
2827              }                                                                                                     
2828                                                                                                                    
2829              Bundle optsBundle = null;                                                                             
2830              if (useLaunchAnimation) {                                                                             
2831                  ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
2832                          ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       
2833                          ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
2834                  optsBundle = opts.toBundle();                                                                     
2835              }                                                                                                     
2836                                                                                                                    
2837              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
2838                  // Could be launching some bookkeeping activity                                                   
2839                  startActivity(intent, optsBundle);                                                                
2840              } else {                                                                                              
2841                  // TODO Component can be null when shortcuts are supported for secondary user                     
2842                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
2843                          intent.getSourceBounds(), optsBundle);                                                    
2844              }                                                                                                     
2845              return true;                                                                                          
2846          } catch (SecurityException e) {                                                                           
2847              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2848              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
2849                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
2850                      "or use the exported attribute for this activity. "                                           
2851                      + "tag="+ tag + " intent=" + intent, e);                                                      
2852          }                                                                                                         
2853          return false;                                                                                             
2854      }                                                                                                             
2855                                                                                                                    
2856      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
2857          boolean success = false;                                                                                  
2858          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
2859              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
2860              return false;                                                                                         
2861          }                                                                                                         
2862          try {                                                                                                     
2863              success = startActivity(v, intent, tag);                                                              
2864          } catch (ActivityNotFoundException e) {                                                                   
2865              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2866              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
2867          }                                                                                                         
2868          return success;                                                                                           
2869      }                                                                                                             
2870                                                                                                                    
2871      /**                                                                                                           
2872       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
2873       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
2874       */                                                                                                           
2875      private void copyFolderIconToImage(FolderIcon fi) {                                                           
2876          final int width = fi.getMeasuredWidth();                                                                  
2877          final int height = fi.getMeasuredHeight();                                                                
2878                                                                                                                    
2879          // Lazy load ImageView, Bitmap and Canvas                                                                 
2880          if (mFolderIconImageView == null) {                                                                       
2881              mFolderIconImageView = new ImageView(this);                                                           
2882          }                                                                                                         
2883          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
2884                  mFolderIconBitmap.getHeight() != height) {                                                        
2885              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
2886              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
2887          }                                                                                                         
2888                                                                                                                    
2889          DragLayer.LayoutParams lp;                                                                                
2890          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
2891              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
2892          } else {                                                                                                  
2893              lp = new DragLayer.LayoutParams(width, height);                                                       
2894          }                                                                                                         
2895                                                                                                                    
2896          // The layout from which the folder is being opened may be scaled, adjust the starting                    
2897          // view size by this scale factor.                                                                        
2898          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
2899          lp.customPosition = true;                                                                                 
2900          lp.x = mRectForFolderAnimation.left;                                                                      
2901          lp.y = mRectForFolderAnimation.top;                                                                       
2902          lp.width = (int) (scale * width);                                                                         
2903          lp.height = (int) (scale * height);                                                                       
2904                                                                                                                    
2905          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
2906          fi.draw(mFolderIconCanvas);                                                                               
2907          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
2908          if (fi.getFolder() != null) {                                                                             
2909              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
2910              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
2911          }                                                                                                         
2912          // Just in case this image view is still in the drag layer from a previous animation,                     
2913          // we remove it and re-add it.                                                                            
2914          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
2915              mDragLayer.removeView(mFolderIconImageView);                                                          
2916          }                                                                                                         
2917          mDragLayer.addView(mFolderIconImageView, lp);                                                             
2918          if (fi.getFolder() != null) {                                                                             
2919              fi.getFolder().bringToFront();                                                                        
2920          }                                                                                                         
2921      }                                                                                                             
2922                                                                                                                    
2923      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
2924          if (fi == null) return;                                                                                   
2925          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
2926          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
2927          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
2928                                                                                                                    
2929          FolderInfo info = (FolderInfo) fi.getTag();                                                               
2930          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
2931              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
2932              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
2933              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
2934          }                                                                                                         
2935                                                                                                                    
2936          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
2937          copyFolderIconToImage(fi);                                                                                
2938          fi.setVisibility(View.INVISIBLE);                                                                         
2939                                                                                                                    
2940          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
2941                  scaleX, scaleY);                                                                                  
2942          if (Utilities.isLmpOrAbove()) {                                                                           
2943              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
2944          }                                                                                                         
2945          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
2946          oa.start();                                                                                               
2947      }                                                                                                             
2948                                                                                                                    
2949      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
2950          if (fi == null) return;                                                                                   
2951          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
2952          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
2953          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
2954                                                                                                                    
2955          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
2956                                                                                                                    
2957          // We remove and re-draw the FolderIcon in-case it has changed                                            
2958          mDragLayer.removeView(mFolderIconImageView);                                                              
2959          copyFolderIconToImage(fi);                                                                                
2960          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
2961                  scaleX, scaleY);                                                                                  
2962          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
2963          oa.addListener(new AnimatorListenerAdapter() {                                                            
2964              @Override                                                                                             
2965              public void onAnimationEnd(Animator animation) {                                                      
2966                  if (cl != null) {                                                                                 
2967                      cl.clearFolderLeaveBehind();                                                                  
2968                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
2969                      mDragLayer.removeView(mFolderIconImageView);                                                  
2970                      fi.setVisibility(View.VISIBLE);                                                               
2971                  }                                                                                                 
2972              }                                                                                                     
2973          });                                                                                                       
2974          oa.start();                                                                                               
2975      }                                                                                                             
2976                                                                                                                    
2977      /**                                                                                                           
2978       * Opens the user folder described by the specified tag. The opening of the folder                            
2979       * is animated relative to the specified View. If the View is null, no animation                              
2980       * is played.                                                                                                 
2981       *                                                                                                            
2982       * @param folderInfo The FolderInfo describing the folder to open.                                            
2983       */                                                                                                           
2984      public void openFolder(FolderIcon folderIcon) {                                                               
2985          Folder folder = folderIcon.getFolder();                                                                   
2986          FolderInfo info = folder.mInfo;                                                                           
2987                                                                                                                    
2988          info.opened = true;                                                                                       
2989                                                                                                                    
2990          // Just verify that the folder hasn't already been added to the DragLayer.                                
2991          // There was a one-off crash where the folder had a parent already.                                       
2992          if (folder.getParent() == null) {                                                                         
2993              mDragLayer.addView(folder);                                                                           
2994              mDragController.addDropTarget((DropTarget) folder);                                                   
2995          } else {                                                                                                  
2996              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
2997                      folder.getParent() + ").");                                                                   
2998          }                                                                                                         
2999          folder.animateOpen();                                                                                     
3000          growAndFadeOutFolderIcon(folderIcon);                                                                     
3001                                                                                                                    
3002          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3003          // the workspace items                                                                                    
3004          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3005          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3006      }                                                                                                             
3007                                                                                                                    
3008      public void closeFolder() {                                                                                   
3009          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3010          if (folder != null) {                                                                                     
3011              if (folder.isEditingName()) {                                                                         
3012                  folder.dismissEditingName();                                                                      
3013              }                                                                                                     
3014              closeFolder(folder);                                                                                  
3015          }                                                                                                         
3016      }                                                                                                             
3017                                                                                                                    
3018      void closeFolder(Folder folder) {                                                                             
3019          folder.getInfo().opened = false;                                                                          
3020                                                                                                                    
3021          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3022          if (parent != null) {                                                                                     
3023              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3024              shrinkAndFadeInFolderIcon(fi);                                                                        
3025          }                                                                                                         
3026          folder.animateClosed();                                                                                   
3027                                                                                                                    
3028          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3029          // longer occludeds the workspace items                                                                   
3030          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3031      }                                                                                                             
3032                                                                                                                    
3033      public boolean onLongClick(View v) {                                                                          
3034          if (!isDraggingEnabled()) return false;                                                                   
3035          if (isWorkspaceLocked()) return false;                                                                    
3036          if (mState != State.WORKSPACE) return false;                                                              
3037                                                                                                                    
3038          if (v instanceof Workspace) {                                                                             
3039              if (!mWorkspace.isInOverviewMode()) {                                                                 
3040                  if (mWorkspace.enterOverviewMode()) {                                                             
3041                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3042                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3043                      return true;                                                                                  
3044                  } else {                                                                                          
3045                      return false;                                                                                 
3046                  }                                                                                                 
3047              } else {                                                                                              
3048                  return false;                                                                                     
3049              }                                                                                                     
3050          }                                                                                                         
3051                                                                                                                    
3052          CellLayout.CellInfo longClickCellInfo = null;                                                             
3053          View itemUnderLongClick = null;                                                                           
3054          if (v.getTag() instanceof ItemInfo) {                                                                     
3055              ItemInfo info = (ItemInfo) v.getTag();                                                                
3056              longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                
3057              itemUnderLongClick = longClickCellInfo.cell;                                                          
3058              resetAddInfo();                                                                                       
3059          }                                                                                                         
3060                                                                                                                    
3061          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3062          // on hotseat items.                                                                                      
3063          final boolean inHotseat = isHotseatLayout(v);                                                             
3064          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3065          if (allowLongPress && !mDragController.isDragging()) {                                                    
3066              if (itemUnderLongClick == null) {                                                                     
3067                  // User long pressed on empty space                                                               
3068                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3069                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3070                  if (mWorkspace.isInOverviewMode()) {                                                              
3071                      mWorkspace.startReordering(v);                                                                
3072                  } else {                                                                                          
3073                      mWorkspace.enterOverviewMode();                                                               
3074                  }                                                                                                 
3075              } else {                                                                                              
3076                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3077                          mHotseat.getOrderInHotseat(                                                               
3078                                  longClickCellInfo.cellX,                                                          
3079                                  longClickCellInfo.cellY));                                                        
3080                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3081                      // User long pressed on an item                                                               
3082                      mWorkspace.startDrag(longClickCellInfo);                                                      
3083                  }                                                                                                 
3084              }                                                                                                     
3085          }                                                                                                         
3086          return true;                                                                                              
3087      }                                                                                                             
3088                                                                                                                    
3089      boolean isHotseatLayout(View layout) {                                                                        
3090          return mHotseat != null && layout != null &&                                                              
3091                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3092      }                                                                                                             
3093                                                                                                                    
3094      /**                                                                                                           
3095       * Returns the CellLayout of the specified container at the specified screen.                                 
3096       */                                                                                                           
3097      CellLayout getCellLayout(long container, long screenId) {                                                     
3098          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3099              if (mHotseat != null) {                                                                               
3100                  return mHotseat.getLayout();                                                                      
3101              } else {                                                                                              
3102                  return null;                                                                                      
3103              }                                                                                                     
3104          } else {                                                                                                  
3105              return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3106          }                                                                                                         
3107      }                                                                                                             
3108                                                                                                                    
3109      public boolean isAllAppsVisible() {                                                                           
3110          return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3111      }                                                                                                             
3112                                                                                                                    
3113      private void setWorkspaceBackground(boolean workspace) {                                                      
3114          mLauncherView.setBackground(workspace ?                                                                   
3115                  mWorkspaceBackgroundDrawable : null);                                                             
3116      }                                                                                                             
3117                                                                                                                    
3118      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3119          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3120          int curflags = getWindow().getAttributes().flags                                                          
3121                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3122          if (wpflags != curflags) {                                                                                
3123              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3124          }                                                                                                         
3125          setWorkspaceBackground(visible);                                                                          
3126      }                                                                                                             
3127                                                                                                                    
3128      private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3129          if (v instanceof LauncherTransitionable) {                                                                
3130              ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3131          }                                                                                                         
3132      }                                                                                                             
3133                                                                                                                    
3134      private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3135          if (v instanceof LauncherTransitionable) {                                                                
3136              ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3137          }                                                                                                         
3138                                                                                                                    
3139          // Update the workspace transition step as well                                                           
3140          dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3141      }                                                                                                             
3142                                                                                                                    
3143      private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3144          if (v instanceof LauncherTransitionable) {                                                                
3145              ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3146          }                                                                                                         
3147      }                                                                                                             
3148                                                                                                                    
3149      private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3150          if (v instanceof LauncherTransitionable) {                                                                
3151              ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3152          }                                                                                                         
3153                                                                                                                    
3154          // Update the workspace transition step as well                                                           
3155          dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3156      }                                                                                                             
3157                                                                                                                    
3158      /**                                                                                                           
3159       * Things to test when changing the following seven functions.                                                
3160       *   - Home from workspace                                                                                    
3161       *          - from center screen                                                                              
3162       *          - from other screens                                                                              
3163       *   - Home from all apps                                                                                     
3164       *          - from center screen                                                                              
3165       *          - from other screens                                                                              
3166       *   - Back from all apps                                                                                     
3167       *          - from center screen                                                                              
3168       *          - from other screens                                                                              
3169       *   - Launch app from workspace and quit                                                                     
3170       *          - with back                                                                                       
3171       *          - with home                                                                                       
3172       *   - Launch app from all apps and quit                                                                      
3173       *          - with back                                                                                       
3174       *          - with home                                                                                       
3175       *   - Go to a screen that's not the default, then all                                                        
3176       *     apps, and launch and app, and go back                                                                  
3177       *          - with back                                                                                       
3178       *          -with home                                                                                        
3179       *   - On workspace, long press power and go back                                                             
3180       *          - with back                                                                                       
3181       *          - with home                                                                                       
3182       *   - On all apps, long press power and go back                                                              
3183       *          - with back                                                                                       
3184       *          - with home                                                                                       
3185       *   - On workspace, power off                                                                                
3186       *   - On all apps, power off                                                                                 
3187       *   - Launch an app and turn off the screen while in that app                                                
3188       *          - Go back with home key                                                                           
3189       *          - Go back with back key  TODO: make this not go to workspace                                      
3190       *          - From all apps                                                                                   
3191       *          - From workspace                                                                                  
3192       *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3193       *          - From all apps                                                                                   
3194       *          - From the center workspace                                                                       
3195       *          - From another workspace                                                                          
3196       */                                                                                                           
3197                                                                                                                    
3198      /**                                                                                                           
3199       * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3200       * Assumes that the view to show is anchored at either the very top or very bottom                            
3201       * of the screen.                                                                                             
3202       */                                                                                                           
3203      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3204          AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3205          showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3206      }                                                                                                             
3207                                                                                                                    
3208      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3209                                           final AppsCustomizePagedView.ContentType contentType) {                  
3210          if (mStateAnimation != null) {                                                                            
3211              mStateAnimation.setDuration(0);                                                                       
3212              mStateAnimation.cancel();                                                                             
3213              mStateAnimation = null;                                                                               
3214          }                                                                                                         
3215                                                                                                                    
3216          boolean material = Utilities.isLmpOrAbove();                                                              
3217                                                                                                                    
3218          final Resources res = getResources();                                                                     
3219                                                                                                                    
3220          final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                            
3221          final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);                        
3222          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3223          final int itemsAlphaStagger =                                                                             
3224                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3225                                                                                                                    
3226          final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                
3227          final View fromView = mWorkspace;                                                                         
3228          final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3229                                                                                                                    
3230          final ArrayList<View> layerViews = new ArrayList<View>();                                                 
3231                                                                                                                    
3232          Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3233                  Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3234          Animator workspaceAnim =                                                                                  
3235                  mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3236          if (!LauncherAppState.isDisableAllApps()                                                                  
3237                  || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3238              // Set the content type for the all apps/widgets space                                                
3239              mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3240          }                                                                                                         
3241                                                                                                                    
3242          // If for some reason our views aren't initialized, don't animate                                         
3243          boolean initialized = getAllAppsButton() != null;                                                         
3244                                                                                                                    
3245          if (animated && initialized) {                                                                            
3246              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3247              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3248                      toView.findViewById(R.id.apps_customize_pane_content);                                        
3249                                                                                                                    
3250              final View page = content.getPageAt(content.getCurrentPage());                                        
3251              final View revealView = toView.findViewById(R.id.fake_page);                                          
3252                                                                                                                    
3253              final float initialPanelAlpha = 1f;                                                                   
3254                                                                                                                    
3255              final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3256              if (isWidgetTray) {                                                                                   
3257                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3258              } else {                                                                                              
3259                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3260              }                                                                                                     
3261                                                                                                                    
3262              // Hide the real page background, and swap in the fake one                                            
3263              content.setPageBackgroundsVisible(false);                                                             
3264              revealView.setVisibility(View.VISIBLE);                                                               
3265              // We need to hide this view as the animation start will be posted.                                   
3266              revealView.setAlpha(0);                                                                               
3267                                                                                                                    
3268              int width = revealView.getMeasuredWidth();                                                            
3269              int height = revealView.getMeasuredHeight();                                                          
3270              float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3271                                                                                                                    
3272              revealView.setTranslationY(0);                                                                        
3273              revealView.setTranslationX(0);                                                                        
3274                                                                                                                    
3275              // Get the y delta between the center of the page and the center of the all apps button               
3276              int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3277                      getAllAppsButton(), null);                                                                    
3278                                                                                                                    
3279              float alpha = 0;                                                                                      
3280              float xDrift = 0;                                                                                     
3281              float yDrift = 0;                                                                                     
3282              if (material) {                                                                                       
3283                  alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3284                  yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3285                  xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3286              } else {                                                                                              
3287                  yDrift = 2 * height / 3;                                                                          
3288                  xDrift = 0;                                                                                       
3289              }                                                                                                     
3290              final float initAlpha = alpha;                                                                        
3291                                                                                                                    
3292              revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                              
3293              layerViews.add(revealView);                                                                           
3294              PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3295              PropertyValuesHolder panelDriftY =                                                                    
3296                      PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3297              PropertyValuesHolder panelDriftX =                                                                    
3298                      PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3299                                                                                                                    
3300              ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3301                      panelAlpha, panelDriftY, panelDriftX);                                                        
3302                                                                                                                    
3303              panelAlphaAndDrift.setDuration(revealDuration);                                                       
3304              panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3305                                                                                                                    
3306              mStateAnimation.play(panelAlphaAndDrift);                                                             
3307                                                                                                                    
3308              if (page != null) {                                                                                   
3309                  page.setVisibility(View.VISIBLE);                                                                 
3310                  page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                                
3311                  layerViews.add(page);                                                                             
3312                                                                                                                    
3313                  ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3314                  page.setTranslationY(yDrift);                                                                     
3315                  pageDrift.setDuration(revealDuration);                                                            
3316                  pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3317                  pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3318                  mStateAnimation.play(pageDrift);                                                                  
3319                                                                                                                    
3320                  page.setAlpha(0f);                                                                                
3321                  ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3322                  itemsAlpha.setDuration(revealDuration);                                                           
3323                  itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3324                  itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3325                  mStateAnimation.play(itemsAlpha);                                                                 
3326              }                                                                                                     
3327                                                                                                                    
3328              View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3329              pageIndicators.setAlpha(0.01f);                                                                       
3330              ObjectAnimator indicatorsAlpha =                                                                      
3331                      ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3332              indicatorsAlpha.setDuration(revealDuration);                                                          
3333              mStateAnimation.play(indicatorsAlpha);                                                                
3334                                                                                                                    
3335              if (material) {                                                                                       
3336                  final View allApps = getAllAppsButton();                                                          
3337                  int allAppsButtonSize = LauncherAppState.getInstance().                                           
3338                          getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3339                  float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3340                  Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3341                                  height / 2, startRadius, revealRadius);                                           
3342                  reveal.setDuration(revealDuration);                                                               
3343                  reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3344                                                                                                                    
3345                  reveal.addListener(new AnimatorListenerAdapter() {                                                
3346                      public void onAnimationStart(Animator animation) {                                            
3347                          if (!isWidgetTray) {                                                                      
3348                              allApps.setVisibility(View.INVISIBLE);                                                
3349                          }                                                                                         
3350                      }                                                                                             
3351                      public void onAnimationEnd(Animator animation) {                                              
3352                          if (!isWidgetTray) {                                                                      
3353                              allApps.setVisibility(View.VISIBLE);                                                  
3354                          }                                                                                         
3355                      }                                                                                             
3356                  });                                                                                               
3357                  mStateAnimation.play(reveal);                                                                     
3358              }                                                                                                     
3359                                                                                                                    
3360              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3361                  @Override                                                                                         
3362                  public void onAnimationEnd(Animator animation) {                                                  
3363                      dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3364                      dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3365                                                                                                                    
3366                      revealView.setVisibility(View.INVISIBLE);                                                     
3367                      revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                          
3368                      if (page != null) {                                                                           
3369                          page.setLayerType(View.LAYER_TYPE_NONE, null);                                            
3370                      }                                                                                             
3371                      content.setPageBackgroundsVisible(true);                                                      
3372                                                                                                                    
3373                      // Hide the search bar                                                                        
3374                      if (mSearchDropTargetBar != null) {                                                           
3375                          mSearchDropTargetBar.hideSearchBar(false);                                                
3376                      }                                                                                             
3377                  }                                                                                                 
3378                                                                                                                    
3379              });                                                                                                   
3380                                                                                                                    
3381              if (workspaceAnim != null) {                                                                          
3382                  mStateAnimation.play(workspaceAnim);                                                              
3383              }                                                                                                     
3384                                                                                                                    
3385              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3386              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3387              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3388              final Runnable startAnimRunnable = new Runnable() {                                                   
3389                  public void run() {                                                                               
3390                      // Check that mStateAnimation hasn't changed while                                            
3391                      // we waited for a layout/draw pass                                                           
3392                      if (mStateAnimation != stateAnimation)                                                        
3393                          return;                                                                                   
3394                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3395                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3396                                                                                                                    
3397                      revealView.setAlpha(initAlpha);                                                               
3398                      if (Utilities.isLmpOrAbove()) {                                                               
3399                          for (int i = 0; i < layerViews.size(); i++) {                                             
3400                              View v = layerViews.get(i);                                                           
3401                              if (v != null) {                                                                      
3402                                  boolean attached = true;                                                          
3403                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                        
3404                                      attached = v.isAttachedToWindow();                                            
3405                                  }                                                                                 
3406                                  if (attached) v.buildLayer();                                                     
3407                              }                                                                                     
3408                          }                                                                                         
3409                      }                                                                                             
3410                      mStateAnimation.start();                                                                      
3411                  }                                                                                                 
3412              };                                                                                                    
3413              toView.bringToFront();                                                                                
3414              toView.setVisibility(View.VISIBLE);                                                                   
3415              toView.post(startAnimRunnable);                                                                       
3416          } else {                                                                                                  
3417              toView.setTranslationX(0.0f);                                                                         
3418              toView.setTranslationY(0.0f);                                                                         
3419              toView.setScaleX(1.0f);                                                                               
3420              toView.setScaleY(1.0f);                                                                               
3421              toView.setVisibility(View.VISIBLE);                                                                   
3422              toView.bringToFront();                                                                                
3423                                                                                                                    
3424              if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3425                  // Hide the search bar                                                                            
3426                  if (mSearchDropTargetBar != null) {                                                               
3427                      mSearchDropTargetBar.hideSearchBar(false);                                                    
3428                  }                                                                                                 
3429              }                                                                                                     
3430              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3431              dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3432              dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3433              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3434              dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3435              dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3436          }                                                                                                         
3437      }                                                                                                             
3438                                                                                                                    
3439      /**                                                                                                           
3440       * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3441       * This is the opposite of showAppsCustomizeHelper.                                                           
3442       * @param animated If true, the transition will be animated.                                                  
3443       */                                                                                                           
3444      private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3445              final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3446                                                                                                                    
3447          if (mStateAnimation != null) {                                                                            
3448              mStateAnimation.setDuration(0);                                                                       
3449              mStateAnimation.cancel();                                                                             
3450              mStateAnimation = null;                                                                               
3451          }                                                                                                         
3452                                                                                                                    
3453          boolean material = Utilities.isLmpOrAbove();                                                              
3454          Resources res = getResources();                                                                           
3455                                                                                                                    
3456          final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                           
3457          final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);                    
3458          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3459          final int itemsAlphaStagger =                                                                             
3460                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3461                                                                                                                    
3462          final float scaleFactor = (float)                                                                         
3463                  res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                                    
3464          final View fromView = mAppsCustomizeTabHost;                                                              
3465          final View toView = mWorkspace;                                                                           
3466          Animator workspaceAnim = null;                                                                            
3467          final ArrayList<View> layerViews = new ArrayList<View>();                                                 
3468                                                                                                                    
3469          if (toState == Workspace.State.NORMAL) {                                                                  
3470              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3471                      toState, animated, layerViews);                                                               
3472          } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3473                  toState == Workspace.State.OVERVIEW) {                                                            
3474              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3475                      toState, animated, layerViews);                                                               
3476          }                                                                                                         
3477                                                                                                                    
3478          // If for some reason our views aren't initialized, don't animate                                         
3479          boolean initialized = getAllAppsButton() != null;                                                         
3480                                                                                                                    
3481          if (animated && initialized) {                                                                            
3482              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3483              if (workspaceAnim != null) {                                                                          
3484                  mStateAnimation.play(workspaceAnim);                                                              
3485              }                                                                                                     
3486                                                                                                                    
3487              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3488                      fromView.findViewById(R.id.apps_customize_pane_content);                                      
3489                                                                                                                    
3490              final View page = content.getPageAt(content.getNextPage());                                           
3491                                                                                                                    
3492              // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3493              int count = content.getChildCount();                                                                  
3494              for (int i = 0; i < count; i++) {                                                                     
3495                  View child = content.getChildAt(i);                                                               
3496                  if (child != page) {                                                                              
3497                      child.setVisibility(View.INVISIBLE);                                                          
3498                  }                                                                                                 
3499              }                                                                                                     
3500              final View revealView = fromView.findViewById(R.id.fake_page);                                        
3501                                                                                                                    
3502              // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3503              // don't perform all these no-op animations. In particularly, this was causing                        
3504              // the all-apps button to pop in and out.                                                             
3505              if (fromView.getVisibility() == View.VISIBLE) {                                                       
3506                  AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3507                  final boolean isWidgetTray =                                                                      
3508                          contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3509                                                                                                                    
3510                  if (isWidgetTray) {                                                                               
3511                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3512                  } else {                                                                                          
3513                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3514                  }                                                                                                 
3515                                                                                                                    
3516                  int width = revealView.getMeasuredWidth();                                                        
3517                  int height = revealView.getMeasuredHeight();                                                      
3518                  float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3519                                                                                                                    
3520                  // Hide the real page background, and swap in the fake one                                        
3521                  revealView.setVisibility(View.VISIBLE);                                                           
3522                  content.setPageBackgroundsVisible(false);                                                         
3523                                                                                                                    
3524                  final View allAppsButton = getAllAppsButton();                                                    
3525                  revealView.setTranslationY(0);                                                                    
3526                  int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3527                          allAppsButton, null);                                                                     
3528                                                                                                                    
3529                  float xDrift = 0;                                                                                 
3530                  float yDrift = 0;                                                                                 
3531                  if (material) {                                                                                   
3532                      yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3533                      xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3534                  } else {                                                                                          
3535                      yDrift = 5 * height / 4;                                                                      
3536                      xDrift = 0;                                                                                   
3537                  }                                                                                                 
3538                                                                                                                    
3539                  revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                          
3540                  TimeInterpolator decelerateInterpolator = material ?                                              
3541                          new LogDecelerateInterpolator(100, 0) :                                                   
3542                          new LogDecelerateInterpolator(30, 0);                                                     
3543                                                                                                                    
3544                  // The vertical motion of the apps panel should be delayed by one frame                           
3545                  // from the conceal animation in order to give the right feel. We correpsondingly                 
3546                  // shorten the duration so that the slide and conceal end at the same time.                       
3547                  ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3548                          0, yDrift);                                                                               
3549                  panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3550                  panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3551                  panelDriftY.setInterpolator(decelerateInterpolator);                                              
3552                  mStateAnimation.play(panelDriftY);                                                                
3553                                                                                                                    
3554                  ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3555                          0, xDrift);                                                                               
3556                  panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3557                  panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3558                  panelDriftX.setInterpolator(decelerateInterpolator);                                              
3559                  mStateAnimation.play(panelDriftX);                                                                
3560                                                                                                                    
3561                  if (isWidgetTray || !material) {                                                                  
3562                      float finalAlpha = material ? 0.4f : 0f;                                                      
3563                      revealView.setAlpha(1f);                                                                      
3564                      ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3565                              1f, finalAlpha);                                                                      
3566                      panelAlpha.setDuration(revealDuration);                                                       
3567                      panelAlpha.setInterpolator(material ? decelerateInterpolator :                                
3568                          new AccelerateInterpolator(1.5f));                                                        
3569                      mStateAnimation.play(panelAlpha);                                                             
3570                  }                                                                                                 
3571                                                                                                                    
3572                  if (page != null) {                                                                               
3573                      page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                            
3574                                                                                                                    
3575                      ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3576                              0, yDrift);                                                                           
3577                      page.setTranslationY(0);                                                                      
3578                      pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3579                      pageDrift.setInterpolator(decelerateInterpolator);                                            
3580                      pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3581                      mStateAnimation.play(pageDrift);                                                              
3582                                                                                                                    
3583                      page.setAlpha(1f);                                                                            
3584                      ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3585                      itemsAlpha.setDuration(100);                                                                  
3586                      itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3587                      mStateAnimation.play(itemsAlpha);                                                             
3588                  }                                                                                                 
3589                                                                                                                    
3590                  View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3591                  pageIndicators.setAlpha(1f);                                                                      
3592                  ObjectAnimator indicatorsAlpha =                                                                  
3593                          LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3594                  indicatorsAlpha.setDuration(revealDuration);                                                      
3595                  indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3596                  mStateAnimation.play(indicatorsAlpha);                                                            
3597                                                                                                                    
3598                  width = revealView.getMeasuredWidth();                                                            
3599                                                                                                                    
3600                  if (material) {                                                                                   
3601                      if (!isWidgetTray) {                                                                          
3602                          allAppsButton.setVisibility(View.INVISIBLE);                                              
3603                      }                                                                                             
3604                      int allAppsButtonSize = LauncherAppState.getInstance().                                       
3605                              getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3606                      float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3607                      Animator reveal =                                                                             
3608                              LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3609                                      height / 2, revealRadius, finalRadius);                                       
3610                      reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3611                      reveal.setDuration(revealDuration);                                                           
3612                      reveal.setStartDelay(itemsAlphaStagger);                                                      
3613                                                                                                                    
3614                      reveal.addListener(new AnimatorListenerAdapter() {                                            
3615                          public void onAnimationEnd(Animator animation) {                                          
3616                              revealView.setVisibility(View.INVISIBLE);                                             
3617                              if (!isWidgetTray) {                                                                  
3618                                  allAppsButton.setVisibility(View.VISIBLE);                                        
3619                              }                                                                                     
3620                          }                                                                                         
3621                      });                                                                                           
3622                                                                                                                    
3623                      mStateAnimation.play(reveal);                                                                 
3624                  }                                                                                                 
3625                                                                                                                    
3626                  dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3627                  dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3628                  mAppsCustomizeContent.stopScrolling();                                                            
3629              }                                                                                                     
3630                                                                                                                    
3631              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3632                  @Override                                                                                         
3633                  public void onAnimationEnd(Animator animation) {                                                  
3634                      fromView.setVisibility(View.GONE);                                                            
3635                      dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3636                      dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3637                      if (onCompleteRunnable != null) {                                                             
3638                          onCompleteRunnable.run();                                                                 
3639                      }                                                                                             
3640                                                                                                                    
3641                      revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                          
3642                      if (page != null) {                                                                           
3643                          page.setLayerType(View.LAYER_TYPE_NONE, null);                                            
3644                      }                                                                                             
3645                      content.setPageBackgroundsVisible(true);                                                      
3646                      // Unhide side pages                                                                          
3647                      int count = content.getChildCount();                                                          
3648                      for (int i = 0; i < count; i++) {                                                             
3649                          View child = content.getChildAt(i);                                                       
3650                          child.setVisibility(View.VISIBLE);                                                        
3651                      }                                                                                             
3652                                                                                                                    
3653                      // Reset page transforms                                                                      
3654                      if (page != null) {                                                                           
3655                          page.setTranslationX(0);                                                                  
3656                          page.setTranslationY(0);                                                                  
3657                          page.setAlpha(1);                                                                         
3658                      }                                                                                             
3659                      content.setCurrentPage(content.getNextPage());                                                
3660                                                                                                                    
3661                      mAppsCustomizeContent.updateCurrentPageScroll();                                              
3662                  }                                                                                                 
3663              });                                                                                                   
3664                                                                                                                    
3665              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3666              final Runnable startAnimRunnable = new Runnable() {                                                   
3667                  public void run() {                                                                               
3668                      // Check that mStateAnimation hasn't changed while                                            
3669                      // we waited for a layout/draw pass                                                           
3670                      if (mStateAnimation != stateAnimation)                                                        
3671                          return;                                                                                   
3672                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3673                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3674                                                                                                                    
3675                      if (Utilities.isLmpOrAbove()) {                                                               
3676                          for (int i = 0; i < layerViews.size(); i++) {                                             
3677                              View v = layerViews.get(i);                                                           
3678                              if (v != null) {                                                                      
3679                                  boolean attached = true;                                                          
3680                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                        
3681                                      attached = v.isAttachedToWindow();                                            
3682                                  }                                                                                 
3683                                  if (attached) v.buildLayer();                                                     
3684                              }                                                                                     
3685                          }                                                                                         
3686                      }                                                                                             
3687                      mStateAnimation.start();                                                                      
3688                  }                                                                                                 
3689              };                                                                                                    
3690              fromView.post(startAnimRunnable);                                                                     
3691          } else {                                                                                                  
3692              fromView.setVisibility(View.GONE);                                                                    
3693              dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
3694              dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
3695              dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
3696              dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
3697              dispatchOnLauncherTransitionStart(toView, animated, true);                                            
3698              dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
3699          }                                                                                                         
3700      }                                                                                                             
3701                                                                                                                    
3702      @Override                                                                                                     
3703      public void onTrimMemory(int level) {                                                                         
3704          super.onTrimMemory(level);                                                                                
3705          if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                                  
3706              mAppsCustomizeTabHost.onTrimMemory();                                                                 
3707          }                                                                                                         
3708      }                                                                                                             
3709                                                                                                                    
3710      protected void showWorkspace(boolean animated) {                                                              
3711          showWorkspace(animated, null);                                                                            
3712      }                                                                                                             
3713                                                                                                                    
3714      protected void showWorkspace() {                                                                              
3715          showWorkspace(true);                                                                                      
3716      }                                                                                                             
3717                                                                                                                    
3718      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
3719          if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
3720              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
3721              mWorkspace.setVisibility(View.VISIBLE);                                                               
3722              hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 
3723                                                                                                                    
3724              // Show the search bar (only animate if we were showing the drop target bar in spring                 
3725              // loaded mode)                                                                                       
3726              if (mSearchDropTargetBar != null) {                                                                   
3727                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
3728              }                                                                                                     
3729                                                                                                                    
3730              // Set focus to the AppsCustomize button                                                              
3731              if (mAllAppsButton != null) {                                                                         
3732                  mAllAppsButton.requestFocus();                                                                    
3733              }                                                                                                     
3734          }                                                                                                         
3735                                                                                                                    
3736          // Change the state *after* we've called all the transition code                                          
3737          mState = State.WORKSPACE;                                                                                 
3738                                                                                                                    
3739          // Resume the auto-advance of widgets                                                                     
3740          mUserPresent = true;                                                                                      
3741          updateRunning();                                                                                          
3742                                                                                                                    
3743          // Send an accessibility event to announce the context change                                             
3744          getWindow().getDecorView()                                                                                
3745                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3746                                                                                                                    
3747          onWorkspaceShown(animated);                                                                               
3748      }                                                                                                             
3749                                                                                                                    
3750      void showOverviewMode(boolean animated) {                                                                     
3751          mWorkspace.setVisibility(View.VISIBLE);                                                                   
3752          hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
3753          mState = State.WORKSPACE;                                                                                 
3754          onWorkspaceShown(animated);                                                                               
3755      }                                                                                                             
3756                                                                                                                    
3757      public void onWorkspaceShown(boolean animated) {                                                              
3758      }                                                                                                             
3759                                                                                                                    
3760      void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
3761                       boolean resetPageToZero) {                                                                   
3762          if (mState != State.WORKSPACE) return;                                                                    
3763                                                                                                                    
3764          if (resetPageToZero) {                                                                                    
3765              mAppsCustomizeTabHost.reset();                                                                        
3766          }                                                                                                         
3767          showAppsCustomizeHelper(animated, false, contentType);                                                    
3768          mAppsCustomizeTabHost.post(new Runnable() {                                                               
3769              @Override                                                                                             
3770              public void run() {                                                                                   
3771                  // We post this in-case the all apps view isn't yet constructed.                                  
3772                  mAppsCustomizeTabHost.requestFocus();                                                             
3773              }                                                                                                     
3774          });                                                                                                       
3775                                                                                                                    
3776          // Change the state *after* we've called all the transition code                                          
3777          mState = State.APPS_CUSTOMIZE;                                                                            
3778                                                                                                                    
3779          // Pause the auto-advance of widgets until we are out of AllApps                                          
3780          mUserPresent = false;                                                                                     
3781          updateRunning();                                                                                          
3782          closeFolder();                                                                                            
3783                                                                                                                    
3784          // Send an accessibility event to announce the context change                                             
3785          getWindow().getDecorView()                                                                                
3786                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3787      }                                                                                                             
3788                                                                                                                    
3789      void enterSpringLoadedDragMode() {                                                                            
3790          if (isAllAppsVisible()) {                                                                                 
3791              hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
3792              mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
3793          }                                                                                                         
3794      }                                                                                                             
3795                                                                                                                    
3796      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
3797              final Runnable onCompleteRunnable) {                                                                  
3798          if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 
3799                                                                                                                    
3800          mHandler.postDelayed(new Runnable() {                                                                     
3801              @Override                                                                                             
3802              public void run() {                                                                                   
3803                  if (successfulDrop) {                                                                             
3804                      // Before we show workspace, hide all apps again because                                      
3805                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
3806                      // clean up our state transition functions                                                    
3807                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
3808                      showWorkspace(true, onCompleteRunnable);                                                      
3809                  } else {                                                                                          
3810                      exitSpringLoadedDragMode();                                                                   
3811                  }                                                                                                 
3812              }                                                                                                     
3813          }, delay);                                                                                                
3814      }                                                                                                             
3815                                                                                                                    
3816      void exitSpringLoadedDragMode() {                                                                             
3817          if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
3818              final boolean animated = true;                                                                        
3819              final boolean springLoaded = true;                                                                    
3820              showAppsCustomizeHelper(animated, springLoaded);                                                      
3821              mState = State.APPS_CUSTOMIZE;                                                                        
3822          }                                                                                                         
3823          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
3824      }                                                                                                             
3825                                                                                                                    
3826      void lockAllApps() {                                                                                          
3827          // TODO                                                                                                   
3828      }                                                                                                             
3829                                                                                                                    
3830      void unlockAllApps() {                                                                                        
3831          // TODO                                                                                                   
3832      }                                                                                                             
3833                                                                                                                    
3834      /**                                                                                                           
3835       * Hides the hotseat area.                                                                                    
3836       */                                                                                                           
3837      void hideHotseat(boolean animated) {                                                                          
3838          if (!LauncherAppState.getInstance().isScreenLarge()) {                                                    
3839              if (animated) {                                                                                       
3840                  if (mHotseat.getAlpha() != 0f) {                                                                  
3841                      int duration = 0;                                                                             
3842                      if (mSearchDropTargetBar != null) {                                                           
3843                          duration = mSearchDropTargetBar.getTransitionOutDuration();                               
3844                      }                                                                                             
3845                      mHotseat.animate().alpha(0f).setDuration(duration);                                           
3846                  }                                                                                                 
3847              } else {                                                                                              
3848                  mHotseat.setAlpha(0f);                                                                            
3849              }                                                                                                     
3850          }                                                                                                         
3851      }                                                                                                             
3852                                                                                                                    
3853      /**                                                                                                           
3854       * Add an item from all apps or customize onto the given workspace screen.                                    
3855       * If layout is null, add to the current screen.                                                              
3856       */                                                                                                           
3857      void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                                    
3858          if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                              
3859              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
3860          }                                                                                                         
3861      }                                                                                                             
3862                                                                                                                    
3863      /** Maps the current orientation to an index for referencing orientation correct global icons */              
3864      private int getCurrentOrientationIndexForGlobalIcons() {                                                      
3865          // default - 0, landscape - 1                                                                             
3866          switch (getResources().getConfiguration().orientation) {                                                  
3867          case Configuration.ORIENTATION_LANDSCAPE:                                                                 
3868              return 1;                                                                                             
3869          default:                                                                                                  
3870              return 0;                                                                                             
3871          }                                                                                                         
3872      }                                                                                                             
3873                                                                                                                    
3874      private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {             
3875          try {                                                                                                     
3876              PackageManager packageManager = getPackageManager();                                                  
3877              // Look for the toolbar icon specified in the activity meta-data                                      
3878              Bundle metaData = packageManager.getActivityInfo(                                                     
3879                      activityName, PackageManager.GET_META_DATA).metaData;                                         
3880              if (metaData != null) {                                                                               
3881                  int iconResId = metaData.getInt(resourceName);                                                    
3882                  if (iconResId != 0) {                                                                             
3883                      Resources res = packageManager.getResourcesForActivity(activityName);                         
3884                      return res.getDrawable(iconResId);                                                            
3885                  }                                                                                                 
3886              }                                                                                                     
3887          } catch (NameNotFoundException e) {                                                                       
3888              // This can happen if the activity defines an invalid drawable                                        
3889              Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +                    
3890                      " not found", e);                                                                             
3891          } catch (Resources.NotFoundException nfe) {                                                               
3892              // This can happen if the activity defines an invalid drawable                                        
3893              Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),                 
3894                      nfe);                                                                                         
3895          }                                                                                                         
3896          return null;                                                                                              
3897      }                                                                                                             
3898                                                                                                                    
3899      // if successful in getting icon, return it; otherwise, set button to use default drawable                    
3900      private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                                  
3901              int buttonId, ComponentName activityName, int fallbackDrawableId,                                     
3902              String toolbarResourceName) {                                                                         
3903          Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);                  
3904          Resources r = getResources();                                                                             
3905          int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                                     
3906          int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                                    
3907                                                                                                                    
3908          TextView button = (TextView) findViewById(buttonId);                                                      
3909          // If we were unable to find the icon via the meta-data, use a generic one                                
3910          if (toolbarIcon == null) {                                                                                
3911              toolbarIcon = r.getDrawable(fallbackDrawableId);                                                      
3912              toolbarIcon.setBounds(0, 0, w, h);                                                                    
3913              if (button != null) {                                                                                 
3914                  button.setCompoundDrawables(toolbarIcon, null, null, null);                                       
3915              }                                                                                                     
3916              return null;                                                                                          
3917          } else {                                                                                                  
3918              toolbarIcon.setBounds(0, 0, w, h);                                                                    
3919              if (button != null) {                                                                                 
3920                  button.setCompoundDrawables(toolbarIcon, null, null, null);                                       
3921              }                                                                                                     
3922              return toolbarIcon.getConstantState();                                                                
3923          }                                                                                                         
3924      }                                                                                                             
3925                                                                                                                    
3926      // if successful in getting icon, return it; otherwise, set button to use default drawable                    
3927      private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                                      
3928              int buttonId, ComponentName activityName, int fallbackDrawableId,                                     
3929              String toolbarResourceName) {                                                                         
3930          ImageView button = (ImageView) findViewById(buttonId);                                                    
3931          Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);                  
3932                                                                                                                    
3933          if (button != null) {                                                                                     
3934              // If we were unable to find the icon via the meta-data, use a                                        
3935              // generic one                                                                                        
3936              if (toolbarIcon == null) {                                                                            
3937                  button.setImageResource(fallbackDrawableId);                                                      
3938              } else {                                                                                              
3939                  button.setImageDrawable(toolbarIcon);                                                             
3940              }                                                                                                     
3941          }                                                                                                         
3942                                                                                                                    
3943          return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                                       
3944                                                                                                                    
3945      }                                                                                                             
3946                                                                                                                    
3947      private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                         
3948          TextView button = (TextView) findViewById(buttonId);                                                      
3949          button.setCompoundDrawables(d, null, null, null);                                                         
3950      }                                                                                                             
3951                                                                                                                    
3952      private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                               
3953          ImageView button = (ImageView) findViewById(buttonId);                                                    
3954          button.setImageDrawable(d.newDrawable(getResources()));                                                   
3955      }                                                                                                             
3956                                                                                                                    
3957      private void invalidatePressedFocusedStates(View container, View button) {                                    
3958          if (container instanceof HolographicLinearLayout) {                                                       
3959              HolographicLinearLayout layout = (HolographicLinearLayout) container;                                 
3960              layout.invalidatePressedFocusedStates();                                                              
3961          } else if (button instanceof HolographicImageView) {                                                      
3962              HolographicImageView view = (HolographicImageView) button;                                            
3963              view.invalidatePressedFocusedStates();                                                                
3964          }                                                                                                         
3965      }                                                                                                             
3966                                                                                                                    
3967      public View getQsbBar() {                                                                                     
3968          if (mQsb == null) {                                                                                       
3969              mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                                  
3970              mSearchDropTargetBar.addView(mQsb);                                                                   
3971          }                                                                                                         
3972          return mQsb;                                                                                              
3973      }                                                                                                             
3974                                                                                                                    
3975      protected boolean updateGlobalSearchIcon() {                                                                  
3976          final View searchButtonContainer = findViewById(R.id.search_button_container);                            
3977          final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                              
3978          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
3979          final View voiceButton = findViewById(R.id.voice_button);                                                 
3980                                                                                                                    
3981          final SearchManager searchManager =                                                                       
3982                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                         
3983          ComponentName activityName = searchManager.getGlobalSearchActivity();                                     
3984          if (activityName != null) {                                                                               
3985              int coi = getCurrentOrientationIndexForGlobalIcons();                                                 
3986              sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                    
3987                      R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,                      
3988                      TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                           
3989              if (sGlobalSearchIcon[coi] == null) {                                                                 
3990                  sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                
3991                          R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,                  
3992                          TOOLBAR_ICON_METADATA_NAME);                                                              
3993              }                                                                                                     
3994                                                                                                                    
3995              if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);                 
3996              searchButton.setVisibility(View.VISIBLE);                                                             
3997              invalidatePressedFocusedStates(searchButtonContainer, searchButton);                                  
3998              return true;                                                                                          
3999          } else {                                                                                                  
4000              // We disable both search and voice search when there is no global search provider                    
4001              if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);                    
4002              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);                      
4003              if (searchButton != null) searchButton.setVisibility(View.GONE);                                      
4004              if (voiceButton != null) voiceButton.setVisibility(View.GONE);                                        
4005              updateVoiceButtonProxyVisible(false);                                                                 
4006              return false;                                                                                         
4007          }                                                                                                         
4008      }                                                                                                             
4009                                                                                                                    
4010      protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                             
4011          final View searchButtonContainer = findViewById(R.id.search_button_container);                            
4012          final View searchButton = (ImageView) findViewById(R.id.search_button);                                   
4013          updateButtonWithDrawable(R.id.search_button, d);                                                          
4014          invalidatePressedFocusedStates(searchButtonContainer, searchButton);                                      
4015      }                                                                                                             
4016                                                                                                                    
4017      protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                              
4018          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4019          final View voiceButton = findViewById(R.id.voice_button);                                                 
4020                                                                                                                    
4021          // We only show/update the voice search icon if the search icon is enabled as well                        
4022          final SearchManager searchManager =                                                                       
4023                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                         
4024          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
4025                                                                                                                    
4026          ComponentName activityName = null;                                                                        
4027          if (globalSearchActivity != null) {                                                                       
4028              // Check if the global search activity handles voice search                                           
4029              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
4030              intent.setPackage(globalSearchActivity.getPackageName());                                             
4031              activityName = intent.resolveActivity(getPackageManager());                                           
4032          }                                                                                                         
4033                                                                                                                    
4034          if (activityName == null) {                                                                               
4035              // Fallback: check if an activity other than the global search activity                               
4036              // resolves this                                                                                      
4037              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
4038              activityName = intent.resolveActivity(getPackageManager());                                           
4039          }                                                                                                         
4040          if (searchVisible && activityName != null) {                                                              
4041              int coi = getCurrentOrientationIndexForGlobalIcons();                                                 
4042              sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                     
4043                      R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,                        
4044                      TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                                     
4045              if (sVoiceSearchIcon[coi] == null) {                                                                  
4046                  sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                 
4047                          R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,                    
4048                          TOOLBAR_ICON_METADATA_NAME);                                                              
4049              }                                                                                                     
4050              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);                   
4051              voiceButton.setVisibility(View.VISIBLE);                                                              
4052              updateVoiceButtonProxyVisible(false);                                                                 
4053              invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                                    
4054              return true;                                                                                          
4055          } else {                                                                                                  
4056              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);                      
4057              if (voiceButton != null) voiceButton.setVisibility(View.GONE);                                        
4058              updateVoiceButtonProxyVisible(false);                                                                 
4059              return false;                                                                                         
4060          }                                                                                                         
4061      }                                                                                                             
4062                                                                                                                    
4063      protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                              
4064          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4065          final View voiceButton = findViewById(R.id.voice_button);                                                 
4066          updateButtonWithDrawable(R.id.voice_button, d);                                                           
4067          invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                                        
4068      }                                                                                                             
4069                                                                                                                    
4070      public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                             
4071          final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                                      
4072          if (voiceButtonProxy != null) {                                                                           
4073              boolean visible = !forceDisableVoiceButtonProxy &&                                                    
4074                      mWorkspace.shouldVoiceButtonProxyBeVisible();                                                 
4075              voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                                   
4076              voiceButtonProxy.bringToFront();                                                                      
4077          }                                                                                                         
4078      }                                                                                                             
4079                                                                                                                    
4080      /**                                                                                                           
4081       * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button proxy   
4082       * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                               
4083       */                                                                                                           
4084      public void disableVoiceButtonProxy(boolean disabled) {                                                       
4085          updateVoiceButtonProxyVisible(disabled);                                                                  
4086      }                                                                                                             
4087                                                                                                                    
4088      @Override                                                                                                     
4089      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4090          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4091          final List<CharSequence> text = event.getText();                                                          
4092          text.clear();                                                                                             
4093          // Populate event with a fake title based on the current state.                                           
4094          if (mState == State.APPS_CUSTOMIZE) {                                                                     
4095              text.add(mAppsCustomizeTabHost.getContentTag());                                                      
4096          } else {                                                                                                  
4097              text.add(getString(R.string.all_apps_home_button_label));                                             
4098          }                                                                                                         
4099          return result;                                                                                            
4100      }                                                                                                             
4101                                                                                                                    
4102      /**                                                                                                           
4103       * Receives notifications when system dialogs are to be closed.                                               
4104       */                                                                                                           
4105      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4106          @Override                                                                                                 
4107          public void onReceive(Context context, Intent intent) {                                                   
4108              closeSystemDialogs();                                                                                 
4109          }                                                                                                         
4110      }                                                                                                             
4111                                                                                                                    
4112      /**                                                                                                           
4113       * Receives notifications whenever the appwidgets are reset.                                                  
4114       */                                                                                                           
4115      private class AppWidgetResetObserver extends ContentObserver {                                                
4116          public AppWidgetResetObserver() {                                                                         
4117              super(new Handler());                                                                                 
4118          }                                                                                                         
4119                                                                                                                    
4120          @Override                                                                                                 
4121          public void onChange(boolean selfChange) {                                                                
4122              onAppWidgetReset();                                                                                   
4123          }                                                                                                         
4124      }                                                                                                             
4125                                                                                                                    
4126      /**                                                                                                           
4127       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4128       * in onResume.                                                                                               
4129       *                                                                                                            
4130       * This needs to be called from incoming places where resources might have been loaded                        
4131       * while we are paused.  That is becaues the Configuration might be wrong                                     
4132       * when we're not running, and if it comes back to what it was when we                                        
4133       * were paused, we are not restarted.                                                                         
4134       *                                                                                                            
4135       * Implementation of the method from LauncherModel.Callbacks.                                                 
4136       *                                                                                                            
4137       * @return true if we are currently paused.  The caller might be able to                                      
4138       * skip some work in that case since we will come back again.                                                 
4139       */                                                                                                           
4140      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4141          if (mPaused) {                                                                                            
4142              Log.i(TAG, "Deferring update until onResume");                                                        
4143              if (deletePreviousRunnables) {                                                                        
4144                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4145                  }                                                                                                 
4146              }                                                                                                     
4147              mBindOnResumeCallbacks.add(run);                                                                      
4148              return true;                                                                                          
4149          } else {                                                                                                  
4150              return false;                                                                                         
4151          }                                                                                                         
4152      }                                                                                                             
4153                                                                                                                    
4154      private boolean waitUntilResume(Runnable run) {                                                               
4155          return waitUntilResume(run, false);                                                                       
4156      }                                                                                                             
4157                                                                                                                    
4158      public void addOnResumeCallback(Runnable run) {                                                               
4159          mOnResumeCallbacks.add(run);                                                                              
4160      }                                                                                                             
4161                                                                                                                    
4162      /**                                                                                                           
4163       * If the activity is currently paused, signal that we need to re-run the loader                              
4164       * in onResume.                                                                                               
4165       *                                                                                                            
4166       * This needs to be called from incoming places where resources might have been loaded                        
4167       * while we are paused.  That is becaues the Configuration might be wrong                                     
4168       * when we're not running, and if it comes back to what it was when we                                        
4169       * were paused, we are not restarted.                                                                         
4170       *                                                                                                            
4171       * Implementation of the method from LauncherModel.Callbacks.                                                 
4172       *                                                                                                            
4173       * @return true if we are currently paused.  The caller might be able to                                      
4174       * skip some work in that case since we will come back again.                                                 
4175       */                                                                                                           
4176      public boolean setLoadOnResume() {                                                                            
4177          if (mPaused) {                                                                                            
4178              Log.i(TAG, "setLoadOnResume");                                                                        
4179              mOnResumeNeedsLoad = true;                                                                            
4180              return true;                                                                                          
4181          } else {                                                                                                  
4182              return false;                                                                                         
4183          }                                                                                                         
4184      }                                                                                                             
4185                                                                                                                    
4186      /**                                                                                                           
4187       * Implementation of the method from LauncherModel.Callbacks.                                                 
4188       */                                                                                                           
4189      public int getCurrentWorkspaceScreen() {                                                                      
4190          if (mWorkspace != null) {                                                                                 
4191              return mWorkspace.getCurrentPage();                                                                   
4192          } else {                                                                                                  
4193              return SCREEN_COUNT / 2;                                                                              
4194          }                                                                                                         
4195      }                                                                                                             
4196                                                                                                                    
4197      /**                                                                                                           
4198       * Refreshes the shortcuts shown on the workspace.                                                            
4199       *                                                                                                            
4200       * Implementation of the method from LauncherModel.Callbacks.                                                 
4201       */                                                                                                           
4202      public void startBinding() {                                                                                  
4203          setWorkspaceLoading(true);                                                                                
4204                                                                                                                    
4205          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4206          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4207          // from scratch again                                                                                     
4208          mBindOnResumeCallbacks.clear();                                                                           
4209                                                                                                                    
4210          // Clear the workspace because it's going to be rebound                                                   
4211          mWorkspace.clearDropTargets();                                                                            
4212          mWorkspace.removeAllWorkspaceScreens();                                                                   
4213                                                                                                                    
4214          mWidgetsToAdvance.clear();                                                                                
4215          if (mHotseat != null) {                                                                                   
4216              mHotseat.resetLayout();                                                                               
4217          }                                                                                                         
4218      }                                                                                                             
4219                                                                                                                    
4220      @Override                                                                                                     
4221      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4222          bindAddScreens(orderedScreenIds);                                                                         
4223                                                                                                                    
4224          // If there are no screens, we need to have an empty screen                                               
4225          if (orderedScreenIds.size() == 0) {                                                                       
4226              mWorkspace.addExtraEmptyScreen();                                                                     
4227          }                                                                                                         
4228                                                                                                                    
4229          // Create the custom content page (this call updates mDefaultScreen which calls                           
4230          // setCurrentPage() so ensure that all pages are added before calling this).                              
4231          if (hasCustomContentToLeft()) {                                                                           
4232              mWorkspace.createCustomContentContainer();                                                            
4233              populateCustomContentContainer();                                                                     
4234          }                                                                                                         
4235      }                                                                                                             
4236                                                                                                                    
4237      @Override                                                                                                     
4238      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4239          // Log to disk                                                                                            
4240          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4241          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4242                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4243          int count = orderedScreenIds.size();                                                                      
4244          for (int i = 0; i < count; i++) {                                                                         
4245              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4246          }                                                                                                         
4247      }                                                                                                             
4248                                                                                                                    
4249      private boolean shouldShowWeightWatcher() {                                                                   
4250          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4251          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4252          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4253                                                                                                                    
4254          return show;                                                                                              
4255      }                                                                                                             
4256                                                                                                                    
4257      private void toggleShowWeightWatcher() {                                                                      
4258          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4259          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4260          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4261                                                                                                                    
4262          show = !show;                                                                                             
4263                                                                                                                    
4264          SharedPreferences.Editor editor = sp.edit();                                                              
4265          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4266          editor.commit();                                                                                          
4267                                                                                                                    
4268          if (mWeightWatcher != null) {                                                                             
4269              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4270          }                                                                                                         
4271      }                                                                                                             
4272                                                                                                                    
4273      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4274                                final ArrayList<ItemInfo> addNotAnimated,                                           
4275                                final ArrayList<ItemInfo> addAnimated,                                              
4276                                final ArrayList<AppInfo> addedApps) {                                               
4277          Runnable r = new Runnable() {                                                                             
4278              public void run() {                                                                                   
4279                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4280              }                                                                                                     
4281          };                                                                                                        
4282          if (waitUntilResume(r)) {                                                                                 
4283              return;                                                                                               
4284          }                                                                                                         
4285                                                                                                                    
4286          // Add the new screens                                                                                    
4287          if (newScreens != null) {                                                                                 
4288              bindAddScreens(newScreens);                                                                           
4289          }                                                                                                         
4290                                                                                                                    
4291          // We add the items without animation on non-visible pages, and with                                      
4292          // animations on the new page (which we will try and snap to).                                            
4293          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4294              bindItems(addNotAnimated, 0,                                                                          
4295                      addNotAnimated.size(), false);                                                                
4296          }                                                                                                         
4297          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4298              bindItems(addAnimated, 0,                                                                             
4299                      addAnimated.size(), true);                                                                    
4300          }                                                                                                         
4301                                                                                                                    
4302          // Remove the extra empty screen                                                                          
4303          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4304                                                                                                                    
4305          if (!LauncherAppState.isDisableAllApps() &&                                                               
4306                  addedApps != null && mAppsCustomizeContent != null) {                                             
4307              mAppsCustomizeContent.addApps(addedApps);                                                             
4308          }                                                                                                         
4309      }                                                                                                             
4310                                                                                                                    
4311      /**                                                                                                           
4312       * Bind the items start-end from the list.                                                                    
4313       *                                                                                                            
4314       * Implementation of the method from LauncherModel.Callbacks.                                                 
4315       */                                                                                                           
4316      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4317                            final boolean forceAnimateIcons) {                                                      
4318          Runnable r = new Runnable() {                                                                             
4319              public void run() {                                                                                   
4320                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4321              }                                                                                                     
4322          };                                                                                                        
4323          if (waitUntilResume(r)) {                                                                                 
4324              return;                                                                                               
4325          }                                                                                                         
4326                                                                                                                    
4327          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4328          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4329          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4330          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4331          Workspace workspace = mWorkspace;                                                                         
4332          long newShortcutsScreenId = -1;                                                                           
4333          for (int i = start; i < end; i++) {                                                                       
4334              final ItemInfo item = shortcuts.get(i);                                                               
4335                                                                                                                    
4336              // Short circuit if we are loading dock items for a configuration which has no dock                   
4337              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4338                      mHotseat == null) {                                                                           
4339                  continue;                                                                                         
4340              }                                                                                                     
4341                                                                                                                    
4342              switch (item.itemType) {                                                                              
4343                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4344                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4345                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4346                      View shortcut = createShortcut(info);                                                         
4347                                                                                                                    
4348                      /*                                                                                            
4349                       * TODO: FIX collision case                                                                   
4350                       */                                                                                           
4351                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4352                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4353                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4354                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4355                              Object tag = v.getTag();                                                              
4356                              String desc = "Collision while binding workspace item: " + item                       
4357                                      + ". Collides with " + tag;                                                   
4358                              if (LauncherAppState.isDogfoodBuild()) {                                              
4359                                  throw (new RuntimeException(desc));                                               
4360                              } else {                                                                              
4361                                  Log.d(TAG, desc);                                                                 
4362                              }                                                                                     
4363                          }                                                                                         
4364                      }                                                                                             
4365                                                                                                                    
4366                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4367                              item.cellY, 1, 1);                                                                    
4368                      if (animateIcons) {                                                                           
4369                          // Animate all the applications up now                                                    
4370                          shortcut.setAlpha(0f);                                                                    
4371                          shortcut.setScaleX(0f);                                                                   
4372                          shortcut.setScaleY(0f);                                                                   
4373                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4374                          newShortcutsScreenId = item.screenId;                                                     
4375                      }                                                                                             
4376                      break;                                                                                        
4377                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4378                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4379                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4380                              (FolderInfo) item, mIconCache);                                                       
4381                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4382                              item.cellY, 1, 1);                                                                    
4383                      break;                                                                                        
4384                  default:                                                                                          
4385                      throw new RuntimeException("Invalid Item Type");                                              
4386              }                                                                                                     
4387          }                                                                                                         
4388                                                                                                                    
4389          if (animateIcons) {                                                                                       
4390              // Animate to the correct page                                                                        
4391              if (newShortcutsScreenId > -1) {                                                                      
4392                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4393                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4394                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4395                      public void run() {                                                                           
4396                          anim.playTogether(bounceAnims);                                                           
4397                          anim.start();                                                                             
4398                      }                                                                                             
4399                  };                                                                                                
4400                  if (newShortcutsScreenId != currentScreenId) {                                                    
4401                      // We post the animation slightly delayed to prevent slowdowns                                
4402                      // when we are loading right after we return to launcher.                                     
4403                      mWorkspace.postDelayed(new Runnable() {                                                       
4404                          public void run() {                                                                       
4405                              if (mWorkspace != null) {                                                             
4406                                  mWorkspace.snapToPage(newScreenIndex);                                            
4407                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4408                                          NEW_APPS_ANIMATION_DELAY);                                                
4409                              }                                                                                     
4410                          }                                                                                         
4411                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4412                  } else {                                                                                          
4413                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4414                  }                                                                                                 
4415              }                                                                                                     
4416          }                                                                                                         
4417          workspace.requestLayout();                                                                                
4418      }                                                                                                             
4419                                                                                                                    
4420      /**                                                                                                           
4421       * Implementation of the method from LauncherModel.Callbacks.                                                 
4422       */                                                                                                           
4423      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4424          Runnable r = new Runnable() {                                                                             
4425              public void run() {                                                                                   
4426                  bindFolders(folders);                                                                             
4427              }                                                                                                     
4428          };                                                                                                        
4429          if (waitUntilResume(r)) {                                                                                 
4430              return;                                                                                               
4431          }                                                                                                         
4432          sFolders.clear();                                                                                         
4433          sFolders.putAll(folders);                                                                                 
4434      }                                                                                                             
4435                                                                                                                    
4436      /**                                                                                                           
4437       * Add the views for a widget to the workspace.                                                               
4438       *                                                                                                            
4439       * Implementation of the method from LauncherModel.Callbacks.                                                 
4440       */                                                                                                           
4441      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4442          Runnable r = new Runnable() {                                                                             
4443              public void run() {                                                                                   
4444                  bindAppWidget(item);                                                                              
4445              }                                                                                                     
4446          };                                                                                                        
4447          if (waitUntilResume(r)) {                                                                                 
4448              return;                                                                                               
4449          }                                                                                                         
4450                                                                                                                    
4451          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4452          if (DEBUG_WIDGETS) {                                                                                      
4453              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4454          }                                                                                                         
4455          final Workspace workspace = mWorkspace;                                                                   
4456                                                                                                                    
4457          AppWidgetProviderInfo appWidgetInfo;                                                                      
4458          if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&                        
4459                  ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                          
4460                                                                                                                    
4461              appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);               
4462              if (appWidgetInfo == null) {                                                                          
4463                  if (DEBUG_WIDGETS) {                                                                              
4464                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4465                              + " belongs to component " + item.providerName                                        
4466                              + ", as the povider is null");                                                        
4467                  }                                                                                                 
4468                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4469                  return;                                                                                           
4470              }                                                                                                     
4471              // Note: This assumes that the id remap broadcast is received before this step.                       
4472              // If that is not the case, the id remap will be ignored and user may see the                         
4473              // click to setup view.                                                                               
4474              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);               
4475              pendingInfo.spanX = item.spanX;                                                                       
4476              pendingInfo.spanY = item.spanY;                                                                       
4477              pendingInfo.minSpanX = item.minSpanX;                                                                 
4478              pendingInfo.minSpanY = item.minSpanY;                                                                 
4479              Bundle options =                                                                                      
4480                      AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
4481                                                                                                                    
4482              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4483              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4484                      newWidgetId, appWidgetInfo, options);                                                         
4485                                                                                                                    
4486              // TODO consider showing a permission dialog when the widget is clicked.                              
4487              if (!success) {                                                                                       
4488                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4489                  if (DEBUG_WIDGETS) {                                                                              
4490                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4491                              + " belongs to component " + item.providerName                                        
4492                              + ", as the launcher is unable to bing a new widget id");                             
4493                  }                                                                                                 
4494                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4495                  return;                                                                                           
4496              }                                                                                                     
4497                                                                                                                    
4498              item.appWidgetId = newWidgetId;                                                                       
4499                                                                                                                    
4500              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4501              // the widget is ready to go.                                                                         
4502              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4503                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4504                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4505                                                                                                                    
4506              LauncherModel.updateItemInDatabase(this, item);                                                       
4507          }                                                                                                         
4508                                                                                                                    
4509          if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                                      
4510              final int appWidgetId = item.appWidgetId;                                                             
4511              appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                                      
4512              if (DEBUG_WIDGETS) {                                                                                  
4513                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidgetInfo.prov🔵
4514              }                                                                                                     
4515                                                                                                                    
4516              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4517          } else {                                                                                                  
4518              appWidgetInfo = null;                                                                                 
4519              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                             
4520              view.updateIcon(mIconCache);                                                                          
4521              item.hostView = view;                                                                                 
4522              item.hostView.updateAppWidget(null);                                                                  
4523              item.hostView.setOnClickListener(this);                                                               
4524          }                                                                                                         
4525                                                                                                                    
4526          item.hostView.setTag(item);                                                                               
4527          item.onBindAppWidget(this);                                                                               
4528                                                                                                                    
4529          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4530                  item.cellY, item.spanX, item.spanY, false);                                                       
4531          addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                             
4532                                                                                                                    
4533          workspace.requestLayout();                                                                                
4534                                                                                                                    
4535          if (DEBUG_WIDGETS) {                                                                                      
4536              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4537                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4538          }                                                                                                         
4539      }                                                                                                             
4540                                                                                                                    
4541      /**                                                                                                           
4542       * Restores a pending widget.                                                                                 
4543       *                                                                                                            
4544       * @param appWidgetId The app widget id                                                                       
4545       * @param cellInfo The position on screen where to create the widget.                                         
4546       */                                                                                                           
4547      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4548          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4549          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4550              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4551              return;                                                                                               
4552          }                                                                                                         
4553                                                                                                                    
4554          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4555          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4556                                                                                                                    
4557          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4558          LauncherModel.updateItemInDatabase(this, info);                                                           
4559      }                                                                                                             
4560                                                                                                                    
4561      public void onPageBoundSynchronously(int page) {                                                              
4562          mSynchronouslyBoundPages.add(page);                                                                       
4563      }                                                                                                             
4564                                                                                                                    
4565      /**                                                                                                           
4566       * Callback saying that there aren't any more items to bind.                                                  
4567       *                                                                                                            
4568       * Implementation of the method from LauncherModel.Callbacks.                                                 
4569       */                                                                                                           
4570      public void finishBindingItems(final boolean upgradePath) {                                                   
4571          Runnable r = new Runnable() {                                                                             
4572              public void run() {                                                                                   
4573                  finishBindingItems(upgradePath);                                                                  
4574              }                                                                                                     
4575          };                                                                                                        
4576          if (waitUntilResume(r)) {                                                                                 
4577              return;                                                                                               
4578          }                                                                                                         
4579          if (mSavedState != null) {                                                                                
4580              if (!mWorkspace.hasFocus()) {                                                                         
4581                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4582              }                                                                                                     
4583              mSavedState = null;                                                                                   
4584          }                                                                                                         
4585                                                                                                                    
4586          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4587                                                                                                                    
4588          setWorkspaceLoading(false);                                                                               
4589          sendLoadingCompleteBroadcastIfNecessary();                                                                
4590                                                                                                                    
4591          // If we received the result of any pending adds while the loader was running (e.g. the                   
4592          // widget configuration forced an orientation change), process them now.                                  
4593          if (sPendingAddItem != null) {                                                                            
4594              final long screenId = completeAdd(sPendingAddItem);                                                   
4595                                                                                                                    
4596              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4597              // the screen would be guaranteed to exist after bind, and the page would be set through              
4598              // the workspace restore process.                                                                     
4599              mWorkspace.post(new Runnable() {                                                                      
4600                  @Override                                                                                         
4601                  public void run() {                                                                               
4602                      mWorkspace.snapToScreenId(screenId);                                                          
4603                  }                                                                                                 
4604              });                                                                                                   
4605              sPendingAddItem = null;                                                                               
4606          }                                                                                                         
4607                                                                                                                    
4608          if (upgradePath) {                                                                                        
4609              mWorkspace.getUniqueComponents(true, null);                                                           
4610              mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4611          }                                                                                                         
4612          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
4613 +        mModel.recheckRestoredItems(this);                                                                        
4614      }                                                                                                             
4615                                                                                                                    
4616      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4617          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4618              String permission =                                                                                   
4619                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4620              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4621              sendBroadcast(intent, permission);                                                                    
4622              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4623              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4624              editor.apply();                                                                                       
4625          }                                                                                                         
4626      }                                                                                                             
4627                                                                                                                    
4628      public boolean isAllAppsButtonRank(int rank) {                                                                
4629          if (mHotseat != null) {                                                                                   
4630              return mHotseat.isAllAppsButtonRank(rank);                                                            
4631          }                                                                                                         
4632          return false;                                                                                             
4633      }                                                                                                             
4634                                                                                                                    
4635      private boolean canRunNewAppsAnimation() {                                                                    
4636          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4637          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4638      }                                                                                                             
4639                                                                                                                    
4640      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4641          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4642                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4643                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4644                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4645          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4646          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4647          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4648          return bounceAnim;                                                                                        
4649      }                                                                                                             
4650                                                                                                                    
4651      public boolean useVerticalBarLayout() {                                                                       
4652          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4653                  getDeviceProfile().isVerticalBarLayout();                                                         
4654      }                                                                                                             
4655                                                                                                                    
4656      protected Rect getSearchBarBounds() {                                                                         
4657          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4658                  getDeviceProfile().getSearchBarBounds();                                                          
4659      }                                                                                                             
4660                                                                                                                    
4661      @Override                                                                                                     
4662      public void bindSearchablesChanged() {                                                                        
4663          boolean searchVisible = updateGlobalSearchIcon();                                                         
4664          boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                              
4665          if (mSearchDropTargetBar != null) {                                                                       
4666              mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                            
4667          }                                                                                                         
4668      }                                                                                                             
4669                                                                                                                    
4670      /**                                                                                                           
4671       * Add the icons for all apps.                                                                                
4672       *                                                                                                            
4673       * Implementation of the method from LauncherModel.Callbacks.                                                 
4674       */                                                                                                           
4675      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4676          if (LauncherAppState.isDisableAllApps()) {                                                                
4677              if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4678                  if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4679                      getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4680                              mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4681                  }                                                                                                 
4682                  mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4683              }                                                                                                     
4684              if (mAppsCustomizeContent != null) {                                                                  
4685                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4686                          LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
4687              }                                                                                                     
4688          } else {                                                                                                  
4689              if (mAppsCustomizeContent != null) {                                                                  
4690                  mAppsCustomizeContent.setApps(apps);                                                              
4691                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4692                          LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
4693              }                                                                                                     
4694          }                                                                                                         
4695      }                                                                                                             
4696                                                                                                                    
4697      /**                                                                                                           
4698       * A package was updated.                                                                                     
4699       *                                                                                                            
4700       * Implementation of the method from LauncherModel.Callbacks.                                                 
4701       */                                                                                                           
4702      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
4703          Runnable r = new Runnable() {                                                                             
4704              public void run() {                                                                                   
4705                  bindAppsUpdated(apps);                                                                            
4706              }                                                                                                     
4707          };                                                                                                        
4708          if (waitUntilResume(r)) {                                                                                 
4709              return;                                                                                               
4710          }                                                                                                         
4711                                                                                                                    
4712          if (mWorkspace != null) {                                                                                 
4713              mWorkspace.updateShortcutsAndWidgets(apps);                                                           
4714          }                                                                                                         
4715                                                                                                                    
4716          if (!LauncherAppState.isDisableAllApps() &&                                                               
4717                  mAppsCustomizeContent != null) {                                                                  
4718              mAppsCustomizeContent.updateApps(apps);                                                               
4719 +        }                                                                                                         
4720 +    }                                                                                                             
4721 +                                                                                                                  
4722 +    /**                                                                                                           
4723 +     * Packages were restored                                                                                     
4724 +     */                                                                                                           
4725 +    public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                                 
4726 +        Runnable r = new Runnable() {                                                                             
4727 +            public void run() {                                                                                   
4728 +                bindAppsRestored(apps);                                                                           
4729 +            }                                                                                                     
4730 +        };                                                                                                        
4731 +        if (waitUntilResume(r)) {                                                                                 
4732 +            return;                                                                                               
4733 +        }                                                                                                         
4734 +                                                                                                                  
4735 +        if (mWorkspace != null) {                                                                                 
4736 +            mWorkspace.updateShortcutsAndWidgets(apps);                                                           
4737          }                                                                                                         
4738      }                                                                                                             
4739                                                                                                                    
4740      /**                                                                                                           




















4741       * Update the state of a package, typically related to install state.                                         
4742       *                                                                                                            
4743       * Implementation of the method from LauncherModel.Callbacks.                                                 
4744       */                                                                                                           
4745      @Override                                                                                                     
4746      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
4747          if (mWorkspace != null) {                                                                                 
4748              mWorkspace.updatePackageState(installInfo);                                                           
4749          }                                                                                                         
4750      }                                                                                                             
4751                                                                                                                    
4752      /**                                                                                                           
4753       * Update the label and icon of all the icons in a package                                                    
4754       *                                                                                                            
4755       * Implementation of the method from LauncherModel.Callbacks.                                                 
4756       */                                                                                                           
4757      @Override                                                                                                     
4758      public void updatePackageBadge(String packageName) {                                                          
4759          if (mWorkspace != null) {                                                                                 
4760              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
4761          }                                                                                                         
4762      }                                                                                                             
4763                                                                                                                    
4764      /**                                                                                                           
4765       * A package was uninstalled.  We take both the super set of packageNames                                     
4766       * in addition to specific applications to remove, the reason being that                                      
4767       * this can be called when a package is updated as well.  In that scenario,                                   
4768       * we only remove specific components from the workspace, where as                                            
4769       * package-removal should clear all items by package name.                                                    
4770       *                                                                                                            

4771       * Implementation of the method from LauncherModel.Callbacks.                                                 
4772       */                                                                                                           

4773      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
4774              final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {                                     

4775          Runnable r = new Runnable() {                                                                             
4776              public void run() {                                                                                   
4777                  bindComponentsRemoved(packageNames, appInfos, user);                                              

4778              }                                                                                                     
4779          };                                                                                                        
4780          if (waitUntilResume(r)) {                                                                                 
4781              return;                                                                                               
4782          }                                                                                                         
4783                                                                                                                    
4784          if (!packageNames.isEmpty()) {                                                                            
4785              mWorkspace.removeItemsByPackageName(packageNames, user);                                              
4786          }                                                                                                         
4787          if (!appInfos.isEmpty()) {                                                                                
4788              mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                              









4789          }                                                                                                         
4790                                                                                                                    
4791          // Notify the drag controller                                                                             
4792          mDragController.onAppsRemoved(packageNames, appInfos);                                                    
4793                                                                                                                    
4794          // Update AllApps                                                                                         
4795          if (!LauncherAppState.isDisableAllApps() &&                                                               
4796                  mAppsCustomizeContent != null) {                                                                  
4797              mAppsCustomizeContent.removeApps(appInfos);                                                           
4798          }                                                                                                         
4799      }                                                                                                             
4800                                                                                                                    
4801      /**                                                                                                           
4802       * A number of packages were updated.                                                                         
4803       */                                                                                                           
4804      private ArrayList<Object> mWidgetsAndShortcuts;                                                               
4805      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
4806              public void run() {                                                                                   
4807                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
4808                  mWidgetsAndShortcuts = null;                                                                      
4809              }                                                                                                     
4810          };                                                                                                        
4811      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
4812          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
4813              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
4814              return;                                                                                               
4815          }                                                                                                         
4816                                                                                                                    
4817          // Update the widgets pane                                                                                
4818          if (mAppsCustomizeContent != null) {                                                                      
4819              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
4820          }                                                                                                         
4821      }                                                                                                             
4822                                                                                                                    
4823      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
4824          final Display d = getWindowManager().getDefaultDisplay();                                                 
4825          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
4826          switch (d.getRotation()) {                                                                                
4827          case Surface.ROTATION_0:                                                                                  
4828          case Surface.ROTATION_180:                                                                                
4829              // We are currently in the same basic orientation as the natural orientation                          
4830              naturalOri = configOri;                                                                               
4831              break;                                                                                                
4832          case Surface.ROTATION_90:                                                                                 
4833          case Surface.ROTATION_270:                                                                                
4834              // We are currently in the other basic orientation to the natural orientation                         
4835              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
4836                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
4837              break;                                                                                                
4838          }                                                                                                         
4839                                                                                                                    
4840          int[] oriMap = {                                                                                          
4841                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
4842                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
4843                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
4844                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
4845          };                                                                                                        
4846          // Since the map starts at portrait, we need to offset if this device's natural orientation               
4847          // is landscape.                                                                                          
4848          int indexOffset = 0;                                                                                      
4849          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
4850              indexOffset = 1;                                                                                      
4851          }                                                                                                         
4852          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
4853      }                                                                                                             
4854                                                                                                                    
4855      public boolean isRotationEnabled() {                                                                          
4856          boolean enableRotation = sForceEnableRotation ||                                                          
4857                  getResources().getBoolean(R.bool.allow_rotation);                                                 
4858          return enableRotation;                                                                                    
4859      }                                                                                                             
4860      public void lockScreenOrientation() {                                                                         
4861          if (isRotationEnabled()) {                                                                                
4862              setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                             
4863                      .getConfiguration().orientation));                                                            
4864          }                                                                                                         
4865      }                                                                                                             
4866      public void unlockScreenOrientation(boolean immediate) {                                                      
4867          if (isRotationEnabled()) {                                                                                
4868              if (immediate) {                                                                                      
4869                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
4870              } else {                                                                                              
4871                  mHandler.postDelayed(new Runnable() {                                                             
4872                      public void run() {                                                                           
4873                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
4874                      }                                                                                             
4875                  }, mRestoreScreenOrientationDelay);                                                               
4876              }                                                                                                     
4877          }                                                                                                         
4878      }                                                                                                             
4879                                                                                                                    
4880      /**                                                                                                           
4881       * Called when the SearchBar hint should be changed.                                                          
4882       *                                                                                                            
4883       * @param hint the hint to be displayed in the search bar.                                                    
4884       */                                                                                                           
4885      protected void onSearchBarHintChanged(String hint) {                                                          
4886                                                                                                                    
4887      }                                                                                                             
4888                                                                                                                    
4889      protected boolean isLauncherPreinstalled() {                                                                  
4890          PackageManager pm = getPackageManager();                                                                  
4891          try {                                                                                                     
4892              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
4893              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
4894                  return true;                                                                                      
4895              } else {                                                                                              
4896                  return false;                                                                                     
4897              }                                                                                                     
4898          } catch (NameNotFoundException e) {                                                                       
4899              e.printStackTrace();                                                                                  
4900              return false;                                                                                         
4901          }                                                                                                         
4902      }                                                                                                             
4903                                                                                                                    
4904      /**                                                                                                           
4905       * This method indicates whether or not we should suggest default wallpaper dimensions                        
4906       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
4907       */                                                                                                           
4908      protected boolean overrideWallpaperDimensions() {                                                             
4909          return true;                                                                                              
4910      }                                                                                                             
4911                                                                                                                    
4912      protected boolean shouldClingFocusHotseatApp() {                                                              
4913          return false;                                                                                             
4914      }                                                                                                             
4915      protected String getFirstRunClingSearchBarHint() {                                                            
4916          return "";                                                                                                
4917      }                                                                                                             
4918      protected String getFirstRunCustomContentHint() {                                                             
4919          return "";                                                                                                
4920      }                                                                                                             
4921      protected int getFirstRunFocusedHotseatAppDrawableId() {                                                      
4922          return -1;                                                                                                
4923      }                                                                                                             
4924      protected ComponentName getFirstRunFocusedHotseatAppComponentName() {                                         
4925          return null;                                                                                              
4926      }                                                                                                             
4927      protected int getFirstRunFocusedHotseatAppRank() {                                                            
4928          return -1;                                                                                                
4929      }                                                                                                             
4930      protected String getFirstRunFocusedHotseatAppBubbleTitle() {                                                  
4931          return "";                                                                                                
4932      }                                                                                                             
4933      protected String getFirstRunFocusedHotseatAppBubbleDescription() {                                            
4934          return "";                                                                                                
4935      }                                                                                                             
4936                                                                                                                    
4937      /**                                                                                                           
4938       * To be overridden by subclasses to indicate that there is an activity to launch                             
4939       * before showing the standard launcher experience.                                                           
4940       */                                                                                                           
4941      protected boolean hasFirstRunActivity() {                                                                     
4942          return false;                                                                                             
4943      }                                                                                                             
4944                                                                                                                    
4945      /**                                                                                                           
4946       * To be overridden by subclasses to launch any first run activity                                            
4947       */                                                                                                           
4948      protected Intent getFirstRunActivity() {                                                                      
4949          return null;                                                                                              
4950      }                                                                                                             
4951                                                                                                                    
4952      private boolean shouldRunFirstRunActivity() {                                                                 
4953          return !ActivityManager.isRunningInTestHarness() &&                                                       
4954                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
4955      }                                                                                                             
4956                                                                                                                    
4957      protected boolean hasRunFirstRunActivity() {                                                                  
4958          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
4959      }                                                                                                             
4960                                                                                                                    
4961      public boolean showFirstRunActivity() {                                                                       
4962          if (shouldRunFirstRunActivity() &&                                                                        
4963                  hasFirstRunActivity()) {                                                                          
4964              Intent firstRunIntent = getFirstRunActivity();                                                        
4965              if (firstRunIntent != null) {                                                                         
4966                  startActivity(firstRunIntent);                                                                    
4967                  markFirstRunActivityShown();                                                                      
4968                  return true;                                                                                      
4969              }                                                                                                     
4970          }                                                                                                         
4971          return false;                                                                                             
4972      }                                                                                                             
4973                                                                                                                    
4974      private void markFirstRunActivityShown() {                                                                    
4975          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
4976          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
4977          editor.apply();                                                                                           
4978      }                                                                                                             
4979                                                                                                                    
4980      /**                                                                                                           
4981       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
4982       * screen that must be displayed and dismissed.                                                               
4983       */                                                                                                           
4984      protected boolean hasDismissableIntroScreen() {                                                               
4985          return false;                                                                                             
4986      }                                                                                                             
4987                                                                                                                    
4988      /**                                                                                                           
4989       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
4990       */                                                                                                           
4991      protected View getIntroScreen() {                                                                             
4992          return null;                                                                                              
4993      }                                                                                                             
4994                                                                                                                    
4995      /**                                                                                                           
4996       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
4997       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
4998       */                                                                                                           
4999      private boolean shouldShowIntroScreen() {                                                                     
5000          return hasDismissableIntroScreen() &&                                                                     
5001                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
5002      }                                                                                                             
5003                                                                                                                    
5004      protected void showIntroScreen() {                                                                            
5005          View introScreen = getIntroScreen();                                                                      
5006          changeWallpaperVisiblity(false);                                                                          
5007          if (introScreen != null) {                                                                                
5008              mDragLayer.showOverlayView(introScreen);                                                              
5009          }                                                                                                         
5010      }                                                                                                             
5011                                                                                                                    
5012      public void dismissIntroScreen() {                                                                            
5013          markIntroScreenDismissed();                                                                               
5014          if (showFirstRunActivity()) {                                                                             
5015              // We delay hiding the intro view until the first run activity is showing. This                       
5016              // avoids a blip.                                                                                     
5017              mWorkspace.postDelayed(new Runnable() {                                                               
5018                  @Override                                                                                         
5019                  public void run() {                                                                               
5020                      mDragLayer.dismissOverlayView();                                                              
5021                      showFirstRunClings();                                                                         
5022                  }                                                                                                 
5023              }, ACTIVITY_START_DELAY);                                                                             
5024          } else {                                                                                                  
5025              mDragLayer.dismissOverlayView();                                                                      
5026              showFirstRunClings();                                                                                 
5027          }                                                                                                         
5028          changeWallpaperVisiblity(true);                                                                           
5029      }                                                                                                             
5030                                                                                                                    
5031      private void markIntroScreenDismissed() {                                                                     
5032          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5033          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5034          editor.apply();                                                                                           
5035      }                                                                                                             
5036                                                                                                                    
5037      private void showFirstRunClings() {                                                                           
5038          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5039          // on the device, then we always show the first run cling experience (or if there is no                   
5040          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5041          LauncherClings launcherClings = new LauncherClings(this);                                                 
5042          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5043              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5044                  launcherClings.showMigrationCling();                                                              
5045              } else {                                                                                              
5046                  launcherClings.showLongPressCling(true);                                                          
5047              }                                                                                                     
5048          }                                                                                                         
5049      }                                                                                                             
5050                                                                                                                    
5051      void showWorkspaceSearchAndHotseat() {                                                                        
5052          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5053          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5054          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5055          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5056      }                                                                                                             
5057                                                                                                                    
5058      void hideWorkspaceSearchAndHotseat() {                                                                        
5059          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5060          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5061          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5062          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5063      }                                                                                                             
5064                                                                                                                    
5065      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5066          // Called from search suggestion, not supported in other profiles.                                        
5067          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5068          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5069          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5070                  myUser);                                                                                          
5071          if (activityInfo == null) {                                                                               
5072              return null;                                                                                          
5073          }                                                                                                         
5074          return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         
5075      }                                                                                                             
5076                                                                                                                    
5077      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5078              Bitmap icon) {                                                                                        
5079          // Called from search suggestion, not supported in other profiles.                                        
5080          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5081                  UserHandleCompat.myUserHandle());                                                                 
5082      }                                                                                                             
5083                                                                                                                    
5084      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5085              Bitmap icon, UserHandleCompat user) {                                                                 
5086          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5087          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5088          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5089      }                                                                                                             
5090                                                                                                                    
5091      protected void moveWorkspaceToDefaultScreen() {                                                               
5092          mWorkspace.moveToDefaultScreen(false);                                                                    
5093      }                                                                                                             
5094                                                                                                                    
5095      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5096          dragView.setTag(dragInfo);                                                                                
5097          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5098          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5099      }                                                                                                             
5100                                                                                                                    
5101      @Override                                                                                                     
5102      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5103      }                                                                                                             
5104                                                                                                                    
5105      /**                                                                                                           
5106       * Prints out out state for debugging.                                                                        
5107       */                                                                                                           
5108      public void dumpState() {                                                                                     
5109          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5110          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5111          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5112          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5113          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5114          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5115          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5116          mModel.dumpState();                                                                                       
5117                                                                                                                    
5118          if (mAppsCustomizeContent != null) {                                                                      
5119              mAppsCustomizeContent.dumpState();                                                                    
5120          }                                                                                                         
5121          Log.d(TAG, "END launcher3 dump state");                                                                   
5122      }                                                                                                             
5123                                                                                                                    
5124      @Override                                                                                                     
5125      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5126          super.dump(prefix, fd, writer, args);                                                                     
5127          synchronized (sDumpLogs) {                                                                                
5128              writer.println(" ");                                                                                  
5129              writer.println("Debug logs: ");                                                                       
5130              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5131                  writer.println("  " + sDumpLogs.get(i));                                                          
5132              }                                                                                                     
5133          }                                                                                                         
5134      }                                                                                                             
5135                                                                                                                    
5136      public static void dumpDebugLogsToConsole() {                                                                 
5137          if (DEBUG_DUMP_LOG) {                                                                                     
5138              synchronized (sDumpLogs) {                                                                            
5139                  Log.d(TAG, "");                                                                                   
5140                  Log.d(TAG, "*********************");                                                              
5141                  Log.d(TAG, "Launcher debug logs: ");                                                              
5142                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5143                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5144                  }                                                                                                 
5145                  Log.d(TAG, "*********************");                                                              
5146                  Log.d(TAG, "");                                                                                   
5147              }                                                                                                     
5148          }                                                                                                         
5149      }                                                                                                             
5150                                                                                                                    
5151      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5152          addDumpLog(tag, log, null, debugLog);                                                                     
5153      }                                                                                                             
5154                                                                                                                    
5155      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5156          if (debugLog) {                                                                                           
5157              if (e != null) {                                                                                      
5158                  Log.d(tag, log, e);                                                                               
5159              } else {                                                                                              
5160                  Log.d(tag, log);                                                                                  
5161              }                                                                                                     
5162          }                                                                                                         
5163          if (DEBUG_DUMP_LOG) {                                                                                     
5164              sDateStamp.setTime(System.currentTimeMillis());                                                       
5165              synchronized (sDumpLogs) {                                                                            
5166                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5167                      + (e == null ? "" : (", Exception: " + e)));                                                  
5168              }                                                                                                     
5169          }                                                                                                         
5170      }                                                                                                             
5171                                                                                                                    
5172      public void dumpLogsToLocalData() {                                                                           
5173          if (DEBUG_DUMP_LOG) {                                                                                     
5174              new AsyncTask<Void, Void, Void>() {                                                                   
5175                  public Void doInBackground(Void ... args) {                                                       
5176                      boolean success = false;                                                                      
5177                      sDateStamp.setTime(sRunStart);                                                                
5178                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5179                              + sDateStamp.getDay() + "_"                                                           
5180                              + sDateStamp.getHours() + "-"                                                         
5181                              + sDateStamp.getMinutes() + "_"                                                       
5182                              + sDateStamp.getSeconds() + ".txt";                                                   
5183                                                                                                                    
5184                      FileOutputStream fos = null;                                                                  
5185                      File outFile = null;                                                                          
5186                      try {                                                                                         
5187                          outFile = new File(getFilesDir(), FILENAME);                                              
5188                          outFile.createNewFile();                                                                  
5189                          fos = new FileOutputStream(outFile);                                                      
5190                      } catch (Exception e) {                                                                       
5191                          e.printStackTrace();                                                                      
5192                      }                                                                                             
5193                      if (fos != null) {                                                                            
5194                          PrintWriter writer = new PrintWriter(fos);                                                
5195                                                                                                                    
5196                          writer.println(" ");                                                                      
5197                          writer.println("Debug logs: ");                                                           
5198                          synchronized (sDumpLogs) {                                                                
5199                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5200                                  writer.println("  " + sDumpLogs.get(i));                                          
5201                              }                                                                                     
5202                          }                                                                                         
5203                          writer.close();                                                                           
5204                      }                                                                                             
5205                      try {                                                                                         
5206                          if (fos != null) {                                                                        
5207                              fos.close();                                                                          
5208                              success = true;                                                                       
5209                          }                                                                                         
5210                      } catch (IOException e) {                                                                     
5211                          e.printStackTrace();                                                                      
5212                      }                                                                                             
5213                      return null;                                                                                  
5214                  }                                                                                                 
5215              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5216          }                                                                                                         
5217      }                                                                                                             
5218  }                                                                                                                 
5219                                                                                                                    
5220  interface LauncherTransitionable {                                                                                
5221      View getContent();                                                                                            
5222      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5223      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5224      void onLauncherTransitionStep(Launcher l, float t);                                                           
5225      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5226  }                                                                                                                 
5227                                                                                                                    
5228  interface DebugIntents {                                                                                          
5229      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5230      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5231  }